1. 13Slhr77Cgzn892

    Posted

    13Slhr77Cgzn892
Changes in title
+GO gorm DB作成 INSERT JSONUnmarshal Mysql
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,273 @@
+こんにちは! GO学習中です!
+
+今回はgormでinsertしてみたいと思います!
+
+[データは前回getしたapi](https://qiita.com/13Slhr77Cgzn892/items/22d4670a201fff221b61)
+のデータを使用します。
+
+DB自体をGOから作成した記事は[こちら](https://qiita.com/13Slhr77Cgzn892/items/7c28e4079e9b7407df6a)です。
+
+
+では始めていきたいと思います。
+
+
+### mysql.go
+
+```go
+// root/app/models/fgi.go
+package mysql
+
+import (
+ "database/sql"
+
+ _ "github.com/go-sql-driver/mysql"
+ "github.com/jinzhu/gorm"
+)
+
+// SQLConnect DB接続
+func SQLConnect() (database *gorm.DB, err error) {
+ DBMS := "mysql"
+ USER := "root"
+ PASS := ""
+ PROTOCOL := "tcp(localhost:3306)"
+ DBNAME := "テーブル名"
+
+ CONNECT := USER + ":" + PASS + "@" + PROTOCOL + "/" + DBNAME + "?charset=utf8&parseTime=true&loc=Asia%2FTokyo"
+ return gorm.Open(DBMS, CONNECT)
+}
+
+```
+ここではDBはすでに作成しているものとします。
+gormとはGOのORMパッケージです。
+
+SQLConnect()の関数ではDBの情報を宣言して、
+
+`return gorm.Open(DBMS, CONNECT)`
+
+とすることでdbと接続しています。
+DB情報はConfigなどにまとめたほうが良いかもしれません。今回はルートユーザーで行なっていきます。
+
+
+### fgi/fgi.go
+
+こちらは[冒頭紹介した記事](https://qiita.com/13Slhr77Cgzn892/items/22d4670a201fff221b61)
+でgetしているapiのファイルです。上記の記事ではgetしただけでしたが、こちらでは
+json.Unmarshalをすることで、用意した構造体に格納しています。
+
+構造体はこちらの [json-to-go](https://mholt.github.io/json-to-go/)
+というサイトで簡単に用意できます。
+
+左側にapiのjsonを貼り付けるとコード内のstructを用意してくれます。
+
+
+```go
+
+package fgi
+
+import (
+ "encoding/json"
+ "io/ioutil"
+ "log"
+ "net/http"
+)
+
+// APIClientFgi api情報格納
+type APIClientFgi struct {
+ key string
+ host string
+ httpClient *http.Client
+}
+
+// New struct生成
+func New(key, host string) *APIClientFgi {
+ fgiClient := &APIClientFgi{key, host, &http.Client{}}
+ return fgiClient
+}
+
+// StructFgi fgi格納
+type StructFgi struct {
+ Fgi struct {
+ Current struct {
+ Value int `json:"value"`
+ ValueText string `json:"valueText"`
+ } `json:"now"`
+ PreviousClose struct {
+ Value int `json:"value"`
+ ValueText string `json:"valueText"`
+ } `json:"previousClose"`
+ OneWeekAgo struct {
+ Value int `json:"value"`
+ ValueText string `json:"valueText"`
+ } `json:"oneWeekAgo"`
+ OneMonthAgo struct {
+ Value int `json:"value"`
+ ValueText string `json:"valueText"`
+ } `json:"oneMonthAgo"`
+ OneYearAgo struct {
+ Value int `json:"value"`
+ ValueText string `json:"valueText"`
+ } `json:"oneYearAgo"`
+ } `json:"fgi"`
+}
+
+// GetFgi api実行
+func (fgi *APIClientFgi) GetFgi() (StructFgi, error) {
+
+ url := "https://fear-and-greed-index.p.rapidapi.com/v1/fgi"
+
+ req, _ := http.NewRequest("GET", url, nil)
+
+ req.Header.Add("x-rapidapi-host", fgi.host)
+ req.Header.Add("x-rapidapi-key", fgi.key)
+
+ res, err := http.DefaultClient.Do(req)
+ if err != nil {
+ return StructFgi{}, nil
+ }
+
+ defer res.Body.Close()
+
+ body, err := ioutil.ReadAll(res.Body)
+ if err != nil {
+ return StructFgi{}, nil
+ }
+
+ var fgiStruct StructFgi
+ if err := json.Unmarshal(body, &fgiStruct); err != nil {
+ log.Fatal(err)
+ }
+
+ return fgiStruct, nil
+}
+```
+
+json-to-goで生成したstructを呼び出しjson.Unmarshalでstructに格納しています。
+
+
+### models/fgi.go
+
+このファイルでは上記でstructに格納したapi情報を展開してDBにINSERTしていきます。
+
+```go
+package models
+
+import (
+ "fmt"
+ "index-indicator-apis/mysql"
+ "time"
+
+ "index-indicator-apis/config"
+ "index-indicator-apis/fgi"
+)
+
+const (
+ tableNameFgis = "fgis"
+)
+
+// Fgis 日足格納
+type Fgis struct {
+ CreatedAt time.Time `json:"created_at,omitempty"`
+ NowValue int `json:"now_value,omitempty"`
+ NowText string `json:"now_text,omitempty"`
+ PcValue int `json:"pc_value,omitempty"`
+ PcText string `json:"pc_text,omitempty"`
+ OneWValue int `json:"one_w_value,omitempty"`
+ OneWText string `json:"one_w_text,omitempty"`
+ OneMValue int `json:"one_m_value,omitempty"`
+ OneMText string `json:"one_m_text,omitempty"`
+ OneYValue int `json:"one_y_value,omitempty"`
+ OneYText string `json:"one_y_text,omitempty"`
+}
+
+//initFgis マイグレーション
+func initFgis() {
+ var err error
+ db, err := mysql.SQLConnect()
+ if err != nil {
+ panic(err.Error())
+ }
+ defer db.Close()
+ db.AutoMigrate(&Fgis{})
+}
+
+// NewFgis fgi.StructFgiを受け取り、Fgisに変換して返す
+
+
+func NewFgis(f fgi.StructFgi) *Fgis {
+ createdAt := time.Now()
+ nowValue := f.Fgi.Current.Value
+ nowText := f.Fgi.Current.ValueText
+ pcValue := f.Fgi.PreviousClose.Value
+ pcText := f.Fgi.PreviousClose.ValueText
+ oneWValue := f.Fgi.OneWeekAgo.Value
+ oneWText := f.Fgi.OneWeekAgo.ValueText
+ oneMValue := f.Fgi.OneMonthAgo.Value
+ oneMText := f.Fgi.OneMonthAgo.ValueText
+ oneYValue := f.Fgi.OneYearAgo.Value
+ oneYText := f.Fgi.OneYearAgo.ValueText
+
+ return &Fgis{
+ createdAt,
+ nowValue,
+ nowText,
+ pcValue,
+ pcText,
+ oneWValue,
+ oneWText,
+ oneMValue,
+ oneMText,
+ oneYValue,
+ oneYText,
+ }
+}
+
+// Create NewFgisをsaveする
+func (f *Fgis) Create() error {
+ db, err := mysql.SQLConnect()
+ if err != nil {
+ panic(err.Error())
+ }
+ defer db.Close()
+ db.Create(&f)
+ return err
+}
+
+// CreateNewFgis migration後にapiを叩きdbに保存する
+func CreateNewFgis() error {
+ // initFgis() migration
+ fgiClient := fgi.New(config.Config.FgiAPIKey, config.Config.FgiAPIHost)
+ f, err := fgiClient.GetFgi()
+ if err != nil {
+ return err
+ }
+ fgi := NewFgis(f)
+ fmt.Println(fgi)
+ fmt.Println(fgi.Create())
+ return err
+}
+
+```
+
+initFgis()ではgormのメソッドをつかってマイグレーションしています。
+apiの情報を先ほどstructに格納したので、それを展開してさらに展開したvalueを格納するstructを用意するということですね。
+ `db.AutoMigrate(&Fgis{})` こちらがgormのメソッド AutoMigrateメソッドです。
+事前に用意した構造体の名前をテーブル名としてマイグレーションしてくれます。この場合だと
+fgisというテーブルがmysqlに作成されます。
+
+`func NewFgis(f fgi.StructFgi) *Fgis{}`
+こちらではapiのデータを格納している StructFgiの中身を展開してINSERTするために用意した構造体(マイグレーションした)の中に格納してます。
+
+`func (f *Fgis) Create() error {}`
+こちらのメソッドではmysqlファイルで作成した関数のSQLConnect()でdbと接続後に
+
+`db.Create(&f)`
+とすることでINSERTを実現しています。 .Createがgormのメソッドです。 .Create(&struct)とすることでテーブル名と対応しているstructの情報をINSERTしてくれます。
+
+最後に`CreateNewFgis()`で用意した関数とメソッドを実行しています。
+
+この関数をmain.goから呼び出せば無事に実行されることができました。
+
+* gormでは主キーとなるIDは自動で生成されるので宣言する必要はありません。
+
+
+以上です!