使用UUID主键且无Gorm Model时,Gorm预加载Has Many关联报错
解决Gorm预加载Has Many关联时的"unsupported relations"错误
使用Gorm时,采用UUID作为主键且未使用Gorm内置Model结构体,同时模型需支持JSON校验。尝试配置Has Many关联(RecordingServer关联多个Camera)并预加载时,出现错误:Cameras: unsupported relations for schema RecordingServer,但执行原生SQL可正常获取关联数据。
报错代码片段
var rs []sdk.RecordingServer err := database.Session.Preload("Cameras").Find(&rs) fmt.Println(err, rs) // 输出错误:Cameras: unsupported relations for schema RecordingServer
原模型定义
type RecordingServerBase struct { Name string `json:"name" gorm:"size:128"` Address string `json:"address" gorm:"size:16"` Cameras []Camera `json:"cameras" gorm:"foreignKey:RecordingServerGuid;type:uuid"` } type RecordingServer struct { Guid uuid.UUID `json:"guid" format:"uuid" gorm:"type:uuid;primaryKey";;` RecordingServerBase } type CameraBase struct { Name string `json:"name" gorm:"size:128"` Address string `json:"address" gorm:"size:16"` Username string `json:"username" gorm:"size:32"` Password string `json:"password" gorm:"size:64"` RecordingServerGuid uuid.UUID } type Camera struct { Guid uuid.UUID `json:"guid" format:"uuid" gorm:"type:uuid;primaryKey";;` CameraBase }
可正常执行的原生SQL
SELECT * FROM `cameras` WHERE recording_server_guid IN ('55c0b198-9ec3-4270-8030-77546ab40c19');
问题原因
- Gorm默认无法自动识别嵌入结构体中的关联关系,缺少显式的主表主键关联配置;
- 模型标签存在冗余分号,虽不影响主键识别,但属于不规范配置。
解决方案
修正后的模型定义
补充关联的references标签指定主表主键,清理冗余符号,同时给外键字段明确类型标签:
type RecordingServerBase struct { Name string `json:"name" gorm:"size:128"` Address string `json:"address" gorm:"size:16"` // 补充references,明确关联主表的Guid主键 Cameras []Camera `json:"cameras" gorm:"foreignKey:RecordingServerGuid;references:Guid;type:uuid"` } type RecordingServer struct { Guid uuid.UUID `json:"guid" format:"uuid" gorm:"type:uuid;primaryKey"` RecordingServerBase } type CameraBase struct { Name string `json:"name" gorm:"size:128"` Address string `json:"address" gorm:"size:16"` Username string `json:"username" gorm:"size:32"` Password string `json:"password" gorm:"size:64"` // 明确外键字段类型,与主表主键保持一致 RecordingServerGuid uuid.UUID `gorm:"type:uuid"` } type Camera struct { Guid uuid.UUID `json:"guid" format:"uuid" gorm:"type:uuid;primaryKey"` CameraBase }
验证预加载
修正模型后,原预加载代码即可正常运行:
var rs []sdk.RecordingServer err := database.Session.Preload("Cameras").Find(&rs) if err != nil { // 错误处理逻辑 } // 每个RecordingServer对象将正确加载关联的Cameras列表
额外说明
- 嵌入结构体定义关联时,必须显式指定
references,否则Gorm无法识别主表关联字段; - 外键字段建议明确类型标签,避免隐式类型转换导致的关联失败;
- 保持标签配置简洁,清理冗余符号。
内容的提问来源于stack exchange,提问作者Jepolin
相关产品推荐
相关产品推荐

