こんにちは! GO学習中です!
今回はgormでinsertしてみたいと思います!
データは前回getしたapi
のデータを使用します。
DB自体をGOから作成した記事はこちらです。
では始めていきたいと思います。
mysql.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
こちらは冒頭紹介した記事
でgetしているapiのファイルです。上記の記事ではgetしただけでしたが、こちらでは
json.Unmarshalをすることで、用意した構造体に格納しています。
構造体はこちらの json-to-go
というサイトで簡単に用意できます。
左側にapiのjsonを貼り付けるとコード内のstructを用意してくれます。
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していきます。
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は自動で生成されるので宣言する必要はありません。
以上です!