Gorm执行Create后结构体RequestID字段为空的问题排查
解决GORM在MariaDB下Create后无法获取自动生成RequestID的问题
核心问题分析
你的问题根源在三个关键点:
- MariaDB版本是否支持
RETURNING子句 - GORM对MariaDB的驱动识别配置缺失
- 结构体中UUID默认值的标签定义错误
分步解决方案
1. 确认MariaDB版本要求
MariaDB 10.5.1及以上版本才原生支持RETURNING子句,如果你的版本低于这个阈值,要么升级MariaDB,要么改用不依赖该子句的方案(比如钩子生成UUID)。
2. 修正GORM数据库驱动配置
GORM默认会将MariaDB当作MySQL处理,而MySQL不支持RETURNING,因此需要显式指定驱动名称为mariadb:
import ( "gorm.io/driver/mysql" "gorm.io/gorm" ) func initDB() (*gorm.DB, error) { dsn := "user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local" db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{ DriverName: "mariadb", // 关键:指定为mariadb驱动类型 }) return db, err }
3. 修正结构体的UUID默认值标签
你当前的default:UUID()标签会被GORM解析成字符串常量,而非调用数据库函数。需要修改为default:(UUID()),确保数据库执行UUID生成逻辑:
type IOSDeviceRequestLog struct { RequestID string `gorm:"primary_key;default:(UUID())" json:"requestId"` // 修正括号包裹函数 DeviceID string `json:"deviceId" gorm:"size:200;not null"` Device IOSDevice `json:"device" gorm:"constraint:OnDelete:CASCADE;"` RequestType string `json:"requestType" gorm:"not null;type:enum ('xxx', 'xxx');"` CreatedAt time.Time `gorm:"autoCreateTime" json:"createdAt"` HandledAt sql.NullTime `json:"handledAt" gorm:"default:null"` }
注意:若你的MariaDB版本无内置
UUID()函数,可改用UUID_SHORT(),或手动创建UUID生成函数。
4. 备选方案:用GORM钩子生成UUID(兼容性更强)
如果不想依赖数据库特性,推荐使用GORM的BeforeCreate钩子在插入前生成UUID,无需RETURNING子句即可直接获取ID:
import "github.com/google/uuid" func (log *IOSDeviceRequestLog) BeforeCreate(tx *gorm.DB) (err error) { if log.RequestID == "" { log.RequestID = uuid.NewString() } return }
验证修复
修改完成后,开启Debug模式运行代码,生成的SQL应包含RETURNING request_id:
INSERT INTO ios_device_request_logs (device_id,request_type,created_at) VALUES ('xxx_device_id_xxx','xxx','2023-01-31 17:47:27.956') RETURNING request_id
此时LOG 2将正确输出自动生成的RequestID。
内容的提问来源于stack exchange,提问作者Antonwy
相关产品推荐
相关产品推荐

