time.Time 的子类型不使用 gorm 库创建列
sub-type of time.Time doesn't create the Column using gorm lib
我正在尝试向数据库添加时间戳,并让返回的 json 带有代表时间戳的数字,而不是时间戳的当前字符串表示;本质上压倒了 time.Time
的 marshal、unmarshal
type JSONTime time.Time
func (j *JSONTime) UnmarshalJSON(data []byte) error {
if string(data) == "null" {
return nil
}
millis, err := strconv.ParseInt(string(data), 10, 64)
if err != nil {
return err
}
*j = JSONTime(time.Unix(0, millis*int64(time.Millisecond)))
return err
}
func (t JSONTime) MarshalJSON() ([]byte, error) {
//do your serializing here
stamp := fmt.Sprintf("%d", time.Time(t).Unix()*1000)
return []byte(stamp), nil
}
type table struct {
ID int64 `gorm:"primary_key;auto_increment"json:"id"`
CreatedAt JSONTime json:"createdAt"`
UpdatedAt JSONTime json:"updatedAt"`
}
我遇到的问题上面的代码只是忽略了在我的数据库中创建列(创建了其他字段)。我什至手动创建了列,但 gorm 也没有添加数据。
我相信编组和解组工作,但问题甚至在使用它们之前就存在(即将列添加到数据库)
我做错了什么?
更新 1:
之前我的 table 结构如下:
type table struct {
ID int64 `gorm:"primary_key;auto_increment"json:"id"`
CreatedAt time.Time json:"createdAt"`
UpdatedAt time.Time json:"updatedAt"`
}
这主要是工作(例如在数据库上创建列)
在数据库连接方面,我基本使用:
root:password@tcp(127.0.0.1:3306)/database?parseTime=true
并为我的存储库使用自动迁移:
db,err := // get db connection
if err != nil {
panic("Failed to connect to database")
}
db.AutoMigrate(&table{})
感谢@mkopriva,我终于弄明白了。
有几个问题:
1- MarshalJSONand
UnmarshalJSON
仅针对数据库交互前后
2- 结构 table
定义不正确 gorm
定义:
type tablestruct {
ID int64 `gorm:"primary_key;auto_increment"json:"id"`
CreatedAt timeLib.JSONTime `gorm:"type:timestamp;default:current_timestamp"json:"createdAt"`
UpdatedAt timeLib.JSONTime `gorm:"type:timestamp;default:current_timestamp ON update current_timestamp"json:"updatedAt"`
}
3-由于类型JSONTime
是一个新类型,驱动程序不知道如何转换它,所以我们需要覆盖Value
:
func (jsonTime JSONTime) Value() (driver.Value, error) {
return time.Time(jsonTime), nil
}
4- 最后我们需要覆盖 Scan
以便将数据库值转换为 JSONTime
值
func (jsonTime *JSONTime) Scan(value interface{}) error {
if value == nil {
*jsonTime = JSONTime(time.Now())
return nil
}
if readTime, err := driver.DefaultParameterConverter.ConvertValue(value); err == nil {
if convertedTime, ok := readTime.(time.Time); ok {
*jsonTime = JSONTime(convertedTime)
return nil
}
}
return errors.New("failed to scan TIME")
}
试一试
type JSONTime struct {
time.Time
}
type BaseModel struct {
ID uint `gorm:"autoIncrement;primary_key" json:"id"`
CreatedAt JSONTime `gorm:"type:timestamp;default:current_timestamp" json:"created_at"`
UpdatedAt JSONTime `gorm:"type:timestamp;default:current_timestamp" json:"updated_at"`
DeletedAt JSONTime `gorm:"type:timestamp;default:current_timestamp" json:"deleted_at"`
}
我正在尝试向数据库添加时间戳,并让返回的 json 带有代表时间戳的数字,而不是时间戳的当前字符串表示;本质上压倒了 time.Time
type JSONTime time.Time
func (j *JSONTime) UnmarshalJSON(data []byte) error {
if string(data) == "null" {
return nil
}
millis, err := strconv.ParseInt(string(data), 10, 64)
if err != nil {
return err
}
*j = JSONTime(time.Unix(0, millis*int64(time.Millisecond)))
return err
}
func (t JSONTime) MarshalJSON() ([]byte, error) {
//do your serializing here
stamp := fmt.Sprintf("%d", time.Time(t).Unix()*1000)
return []byte(stamp), nil
}
type table struct {
ID int64 `gorm:"primary_key;auto_increment"json:"id"`
CreatedAt JSONTime json:"createdAt"`
UpdatedAt JSONTime json:"updatedAt"`
}
我遇到的问题上面的代码只是忽略了在我的数据库中创建列(创建了其他字段)。我什至手动创建了列,但 gorm 也没有添加数据。
我相信编组和解组工作,但问题甚至在使用它们之前就存在(即将列添加到数据库)
我做错了什么?
更新 1:
之前我的 table 结构如下:
type table struct {
ID int64 `gorm:"primary_key;auto_increment"json:"id"`
CreatedAt time.Time json:"createdAt"`
UpdatedAt time.Time json:"updatedAt"`
}
这主要是工作(例如在数据库上创建列)
在数据库连接方面,我基本使用:
root:password@tcp(127.0.0.1:3306)/database?parseTime=true
并为我的存储库使用自动迁移:
db,err := // get db connection
if err != nil {
panic("Failed to connect to database")
}
db.AutoMigrate(&table{})
感谢@mkopriva,我终于弄明白了。
有几个问题:
1- MarshalJSONand
UnmarshalJSON
仅针对数据库交互前后
2- 结构 table
定义不正确 gorm
定义:
type tablestruct {
ID int64 `gorm:"primary_key;auto_increment"json:"id"`
CreatedAt timeLib.JSONTime `gorm:"type:timestamp;default:current_timestamp"json:"createdAt"`
UpdatedAt timeLib.JSONTime `gorm:"type:timestamp;default:current_timestamp ON update current_timestamp"json:"updatedAt"`
}
3-由于类型JSONTime
是一个新类型,驱动程序不知道如何转换它,所以我们需要覆盖Value
:
func (jsonTime JSONTime) Value() (driver.Value, error) {
return time.Time(jsonTime), nil
}
4- 最后我们需要覆盖 Scan
以便将数据库值转换为 JSONTime
值
func (jsonTime *JSONTime) Scan(value interface{}) error {
if value == nil {
*jsonTime = JSONTime(time.Now())
return nil
}
if readTime, err := driver.DefaultParameterConverter.ConvertValue(value); err == nil {
if convertedTime, ok := readTime.(time.Time); ok {
*jsonTime = JSONTime(convertedTime)
return nil
}
}
return errors.New("failed to scan TIME")
}
试一试
type JSONTime struct {
time.Time
}
type BaseModel struct {
ID uint `gorm:"autoIncrement;primary_key" json:"id"`
CreatedAt JSONTime `gorm:"type:timestamp;default:current_timestamp" json:"created_at"`
UpdatedAt JSONTime `gorm:"type:timestamp;default:current_timestamp" json:"updated_at"`
DeletedAt JSONTime `gorm:"type:timestamp;default:current_timestamp" json:"deleted_at"`
}