情况:
我正在使用 postgres 数据库并具有以下结构:
type Building struct {
ID int `json:"id,omitempty"`
Name string `gorm:"size:255" json:"name,omitempty"`
Lon string `gorm:"size:64" json:"lon,omitempty"`
Lat string `gorm:"size:64" json:"lat,omitempty"`
StartTime time.Time `gorm:"type:time" json:"start_time,omitempty"`
EndTime time.Time `gorm:"type:time" json:"end_time,omitempty"`
}
问题:
但是,当我尝试将此结构插入数据库时,会发生以下错误:
解析时间“”10:00:00“”as“”2006-01-02T15:04:05Z07:00“”:不能 解析“0:00”“as”2006“”}。
可能,它无法将StartTime
和EndTime
字段识别为时间类型,而是使用时间戳。如何指定这些字段的类型为时间?
其他信息
以下代码段显示了我的Building
创建:
if err = db.Create(&building).Error; err != nil {
return database.InsertResult{}, err
}
Building表的SQL代码如下:
DROP TABLE IF EXISTS building CASCADE;
CREATE TABLE building(
id SERIAL,
name VARCHAR(255) NOT NULL ,
lon VARCHAR(31) NOT NULL ,
lat VARCHAR(31) NOT NULL ,
start_time TIME NOT NULL ,
end_time TIME NOT NULL ,
PRIMARY KEY (id)
);
答案 0 :(得分:1)
虽然 gorm 不直接支持 TIME 类型,但您始终可以创建自己的类型来实现 sql.Scanner
和 driver.Valuer
接口,以便能够从数据库中放入和取出时间值。
以下是重用/别名 time.Time
,但不使用日、月、年数据的示例实现:
const MyTimeFormat = "15:04:05"
type MyTime time.Time
func NewMyTime(hour, min, sec int) MyTime {
t := time.Date(0, time.January, 1, hour, min, sec, 0, time.UTC)
return MyTime(t)
}
func (t *MyTime) Scan(value interface{}) error {
switch v := value.(type) {
case []byte:
return t.UnmarshalText(string(v))
case string:
return t.UnmarshalText(v)
case time.Time:
*t = MyTime(v)
case nil:
*t = MyTime{}
default:
return fmt.Errorf("cannot sql.Scan() MyTime from: %#v", v)
}
return nil
}
func (t MyTime) Value() (driver.Value, error) {
return driver.Value(time.Time(t).Format(MyTimeFormat)), nil
}
func (t *MyTime) UnmarshalText(value string) error {
dd, err := time.Parse(MyTimeFormat, value)
if err != nil {
return err
}
*t = MyTime(dd)
return nil
}
func (MyTime) GormDataType() string {
return "TIME"
}
你可以像这样使用它:
type Building struct {
ID int `json:"id,omitempty"`
Name string `gorm:"size:255" json:"name,omitempty"`
Lon string `gorm:"size:64" json:"lon,omitempty"`
Lat string `gorm:"size:64" json:"lat,omitempty"`
StartTime MyTime `json:"start_time,omitempty"`
EndTime MyTime `json:"end_time,omitempty"`
}
b := Building{
Name: "test",
StartTime: NewMyTime(10, 23, 59),
}
为了获得适当的 JSON 支持,您需要为 json.Marshaler
/json.Unmarshaler
添加实现,这留给读者作为练习?
答案 1 :(得分:0)
如“How to save time in the database in Go when using GORM and Postgresql?”
中所述目前,GORM不支持
timestamp with time zone
以外的任何日期/时间类型。
因此您可能需要将时间解析为日期:
time.Parse("2006-01-02 3:04PM", "1970-01-01 9:00PM")
答案 2 :(得分:0)
我遇到了同样的错误。似乎数据库中的列类型与 Gorm 模型不匹配
可能数据库中列的类型是您之前可能设置的文本,然后在 gorm 模型中更改了列类型。