GORM自定义接口使用报错:unsupported data问题排查
GORM错误"unsupported data"排查与修复
问题代码
package models import ( "gorm.io/gorm" ) type GormQueryBuilder interface { FindQueryBuilder(db *gorm.DB) *gorm.DB } type BaseInterface interface { Get(GormQueryBuilder, *gorm.DB) error } type Base struct { gorm.Model BaseInterface `gorm:"-"` GormQueryBuilder `gorm:"-"` } func (b *Base) Get(i GormQueryBuilder, db *gorm.DB) error { return i.FindQueryBuilder(db).Find(&i).Error } type A struct { Base B B `gorm:"..."` } func (c *A) FindQueryBuilder(db *gorm.DB) *gorm.DB { return db.Preload("B") } func GetA(c echo.Context) error { tx := db.DB().Begin() defer tx.Commit() a := A{} if err := c.Bind(&a); err != nil { return c.NoContent(http.StatusBadRequest) } x := a.Get(&a, tx) print(x) // rest of the code }
错误原因
报错unsupported data的核心问题在Base.Get方法里:
return i.FindQueryBuilder(db).Find(&i).Error
这里传入Find方法的&i是指向GormQueryBuilder接口的指针,而GORM的Find方法需要接收具体模型结构体的指针——接口类型本身不携带对应数据库表的元数据,GORM无法识别其映射关系,因此抛出不支持的数据类型错误。
修复方案
调整Base的Get方法,直接使用当前实例的指针(因为Base嵌入的模型都实现了GormQueryBuilder接口):
优化后的完整代码
package models import ( "gorm.io/gorm" ) type GormQueryBuilder interface { FindQueryBuilder(db *gorm.DB) *gorm.DB } type Base struct { gorm.Model } // Get方法将当前实例断言为GormQueryBuilder,执行查询并填充自身 func (b *Base) Get(db *gorm.DB) error { qb, ok := b.(GormQueryBuilder) if !ok { return gorm.ErrInvalidData } return qb.FindQueryBuilder(db).Find(b).Error } type A struct { Base B B `gorm:"..."` } func (a *A) FindQueryBuilder(db *gorm.DB) *gorm.DB { return db.Preload("B") } func GetA(c echo.Context) error { tx := db.DB().Begin() defer tx.Commit() a := A{} if err := c.Bind(&a); err != nil { return c.NoContent(http.StatusBadRequest) } // 直接调用Get方法,传入事务DB err := a.Get(tx) print(err) // rest of the code }
修改后,Find方法接收的是具体模型A的指针,GORM可以正常识别模型结构,不会再抛出unsupported data错误。
内容的提问来源于stack exchange,提问作者ZackMelan
相关产品推荐
相关产品推荐

