GORM查询无法返回外键关联的Person表数据,如何解决?
解决GORM关联查询Tenancy和Person数据的问题
你的问题核心是结构体与数据库表的映射不匹配以及关联查询的配置缺失,下面是具体的修复方案:
1. 修正Person结构体的ID类型
数据库中person.id是SERIAL(本质为int类型),但你定义的Person.Id是string,类型不匹配会导致关联时无法正确匹配数据,先把类型改成int:
type Person struct { Id int `json:"id" gorm:"primaryKey;autoIncrement:true"` // 改为int类型 Firstname string `json:"firstname" binding:"required"` Lastname string `json:"lastname" binding:"required"` PhoneNumber string `json:"phoneNumber"` Email string `json:"email" binding:"email"` }
2. 指定结构体对应的数据库表名
GORM默认会把结构体名复数化作为表名(比如Person对应people表),但你的数据库表是person(单数),必须手动指定表名,有两种方式:
方式一:通过gorm标签直接指定
type Person struct { Id int `json:"id" gorm:"primaryKey;autoIncrement:true;tableName:person"` Firstname string `json:"firstname" binding:"required"` Lastname string `json:"lastname" binding:"required"` PhoneNumber string `json:"phoneNumber"` Email string `json:"email" binding:"email"` } type Tenancy struct { Id int `json:"id" gorm:"primaryKey;autoIncrement:true;tableName:tenancy"` TenantId int Tenant Person `json:"tenant" binding:"required" gorm:"foreignKey:TenantId"` StartDate time.Time `json:"start-date" binding:"required"` EndDate time.Time `json:"end-date" binding:"required"` }
方式二:实现Tabler接口
func (Person) TableName() string { return "person" } func (Tenancy) TableName() string { return "tenancy" }
3. 正确执行关联查询
现在可以用两种方式获取关联的Tenant数据:
方式一:使用Preload预加载
var tenancy Tenancy err := db.Preload("Tenant").Where("id=?", id).First(&tenancy).Error
注意:不要额外加
Table("tenancy"),因为已经通过结构体指定了表名,手动指定会覆盖配置,导致Preload找不到正确的关联表。
方式二:使用Joins手动关联查询
如果不想用预加载,也可以直接通过JOIN语句查询:
var tenancy Tenancy err := db.Joins("Tenant").Where("tenancy.id=?", id).First(&tenancy).Error
错误原因说明
你之前执行db.Table("tenancy").Preload("Tenant")时,GORM默认会去查找people表(因为Person结构体默认复数表名),但你的数据库里只有person表,所以会抛出relation "people" does not exist的错误。
内容的提问来源于stack exchange,提问作者user8473984
相关产品推荐
相关产品推荐

