背景
使用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精确到秒级别,二者是不兼容的。