サーバーのバージョンとgorm
パッケージ:
❯ docker exec -it mysql mysqld --version
mysqld Ver 5.7.29 for Linux on x86_64 (MySQL Community Server (GPL))
❯ docker exec -it mysql mysql --version
mysql Ver 14.14 Distrib 5.7.29, for Linux (x86_64) using EditLine wrapper
import "github.com/jinzhu/gorm"
2つのテーブル:
mysql> desc t1;
+------------+-------------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------------+------+-----+-------------------+----------------+
| ... | | | | | |
| created_at | timestamp | YES | | CURRENT_TIMESTAMP | |
+------------+-------------------+------+-----+-------------------+----------------+
mysql> desc t2;
+----------------+------------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+------------------+------+-----+-------------------+----------------+
| ... | ... | ... | ... | ... | ... |
| initiated_at | timestamp | YES | | CURRENT_TIMESTAMP | |
+----------------+------------------+------+-----+-------------------+----------------+
gorm
定義中のモデルstuct{}
は次のとおりです。
// t1
type T1 struct {
ID uint `gorm:"primary_key"`
// others are here
// ...
CreatedAt time.Time `gorm:"timestamp;default:CURRENT_TIMESTAMP" json:"created_at" form:"created_at" query:"created_at" sql:"DEFAULT:current_timestamp"`
}
// t2 ...
type T2 struct {
ID uint `gorm:"primary_key"`
// others are here
// ...
InitiatedAt time.Time `gorm:"timestamp;default:CURRENT_TIMESTAMP" json:"initiated_at" form:"initiated_at" query:"initiated_at" sql:"DEFAULT:current_timestamp"`
}
初期化されていないタイムスタンプで挿入
dbSource := fmt.Sprintf(
"%s:%s@tcp(%s:%s)/%s?charset=utf8&parseTime=True&loc=Local",
cnf.Username,
cnf.Password,
cnf.Host,
cnf.Port,
cnf.DBName,
)
db, err := gorm.Open("mysql", dbSource)
if err != nil {
logrus.Warn("Got error when connect database:", err)
return err
}
t1 := T1{} // created_at is not set
t2 := T2{} // initiated_at is not set
tx := db.Begin()
defer func() {
if r := recover(); r != nil {
logrus.Error("Rolling back")
tx.Rollback()
}
}()
// If failed to begin transaction
if err := tx.Error; err != nil {
return err
}
if err := db.Create(&t1).Error; err != nil {
logrus.Warn(err)
// rollback the transaction in case of error
tx.Rollback()
return derror.ErrorBadRequest
}
if err := db.Create(&t2).Error; err != nil {
logrus.Warn(err)
// rollback the transaction in case of error
tx.Rollback()
return derror.ErrorBadRequest
}
// Or commit the transaction
if err := tx.Commit().Error; err != nil {
logrus.Warn(err)
// rollback the transaction in case of error
tx.Rollback()
return derror.ErrorBadRequest
}
何を選択クエリを実行するか
mysql> select * from t1;
+-----+---------------------+
| ... | created_at |
+-----+---------------------+
| ... | 2020-03-24 02:38:26 |
+-----+---------------------+
mysql> select * from t2;
+-----+---------------------+
| ... | initiated_at |
+-----+---------------------+
| ... | 2020-03-23 20:38:26 |
+-----+---------------------+
期待:
asia/dhaka
(+06:00)リージョンにいることに注意してください。そして、の時間created_at
のt1
テーブルには、私の地域のBST現在の時刻です。一方、時間initiated_at
のt2
テーブルには、UTC現在の時刻です。
しかし、私は両方の時間が同じであることを期待しています(つまり、UTCまたはBSTのどちらかです)。
知りたい:
表ではt1
、を使用してからローカルタイムゾーンでCreatedAt
設定しGorm
ますloc=Local
。
参照:https : //github.com/jinzhu/gorm/blob/master/callback_create.go#L32
そして表にt2
、initiated_at
で設定されていないGorm
、それはによって設定されMysql
ますが、デフォルト値を使用するので、CURRENT_TIMESTAMP
の中でMySql
。
解決:
接続でGorm
タイムゾーンをUTCに変更できloc=UTC
ます。
または
ローカルタイムゾーンをMysql
タイムゾーンとして設定できます。は、time.Time値の場所を設定しますが、MySQLのtime_zone設定は変更しないことに注意してください。そのためには、DSNパラメータとして設定することもできるtime_zoneシステム変数を参照してください。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加