gorm:time.Time类型设置default为CURRENT_TIMESTAMP出错

4 阅读1分钟

背景

使用gorm框架的AutoMigrate函数创建msql table的时候,出现了错误。

go中定义的model

type User struct {
    ID         int       `json:"user_id" gorm:"primaryKey;autoIncrement"`
    Username   string    `json:"username" gorm:"unique;not null"`
    Email      string    `json:"email" gorm:"unique;not null"`
    Password   string    `json:"password" gorm:"not null"`
    Permission string    `json:"permission_level" gorm:"default:'user'"`
    CreateTime time.Time `json:"create_time" gorm:"default:CURRENT_TIMESTAMP"`
    UpdateTime time.Time `json:"update_time" gorm:"default:CURRENT_TIMESTAMP;ON UPDATE CURRENT_TIMESTAMP"`
}

出现错误,Invalid default value for 'create_time'

[39.090ms] [rows:0] CREATE TABLE `users` (`id` bigint AUTO_INCREMENT,`username` varchar(191) NOT NULL,`email` varchar(191) NOT NULL,`password` longtext NOT NULL,`permission` varchar(191) DEFAULT 'user',`create_time` datetime(3) NULL DEFAULT CURRENT_TIMESTAMP,`update_time` datetime(3) NULL DEFAULT CURRENT_TIMESTAMP,PRIMARY KEY (`id`),CONSTRAINT `uni_users_username` UNIQUE (`username`),CONSTRAINT `uni_users_email` UNIQUE (`email`))
2025-02-16T18:46:54.851+0800	FATAL	mysql/init.go:33	failed to auto migrate database schema	{"error": "Error 1067 (42000): Invalid default value for 'create_time'"}

经过

  • 更改sql_mode:禁用STRICT_TRANS_TABLES、NO_ZERO_IN_DATE 和 NO_ZERO_DATE ❌
  • 更改mysql版本:从5.7提升到8.1 ❌
  • 添加gorm的tag,指定类型:type:timestamp
  • 添加gorm的tag,指定类型:type:datetime

example:

type User struct {
    ID         int       `json:"user_id" gorm:"primaryKey;autoIncrement"`
    Username   string    `json:"username" gorm:"unique;not null"`
    Email      string    `json:"email" gorm:"unique;not null"`
    Password   string    `json:"password" gorm:"not null"`
    Permission string    `json:"permission_level" gorm:"default:'user'"`
    CreateTime time.Time `json:"create_time" gorm:"type:datetime;default:CURRENT_TIMESTAMP"`
    UpdateTime time.Time `json:"update_time" gorm:"type:datetime;default:CURRENT_TIMESTAMP;ON UPDATE CURRENT_TIMESTAMP"`
}

原因剖析

gorm框架会默认将golang的「time.Time」类型转化为mysql的「datetime(3)」类型,而datetime(3)精确到毫秒级别,CURRENT_TIMESTAMP精确到秒级别,二者是不兼容的。