datatypes
datatypes copied to clipboard
JSONType field Data: define a valid foreign key for relations or implement the Valuer/Scanner
type (
User struct {
Name string `json:"name"`
Age int `json:"age"`
}
TestTable struct {
ID uint64
Data datatypes.JSONType[*User]
}
)
func (*TestTable) TableName() string {
return "test_table"
}
db.Create(&TestTable{Data: datatypes.JSONType[*User]{Data: &User{Name: "name", Age: 18}}})
row := &datatypes.JSONType[*User]{}
db.Limit(1).Order("id DESC").Pluck("data", row)
// output
// invalid field found for struct gorm.io/datatypes.JSONType[*main.User]'s field Data: define a valid foreign key for relations or implement the Valuer/Scanner interface
fmt.Println(row.Data)
row := &TestTable{}
db.Limit(1).Order("id DESC").Find(row)
fmt.Println(row.Data.Data)
// ok
我来看下这个。
@liyuan1125 I have test, your code miss db.Model(&TestTable{})
part.
I have create a gist here https://gist.github.com/alingse/adbcd450ea6760bac1d41faa07610870#file-queryjsontype-go-L44-L53 and the log
// ok
row := &TestTable{}
db.Limit(1).Order("id DESC").Find(row)
// find all row &{name 18}
fmt.Println("find all row ", row.Data.Data)
// ok
var field datatypes.JSONType[*User]
err = db.Model(&TestTable{}).Limit(1).Order("id DESC").Pluck("data", &field).Error
// find field &{name 18} <nil>
fmt.Println("find field ", field.Data, err)
// ok
var fullRow TestTable
err = db.Model(&TestTable{}).Limit(1).Order("id DESC").Pluck("data", &fullRow.Data).Error
// find field in row <nil> &{name 18}
fmt.Println("find field in row ", err, fullRow.Data.Data)
it query ok, but really got some error log.
[error] invalid field found for struct gorm.io/datatypes.JSONType[*main.User]'s field Data: define a valid foreign key for relations or implement the Valuer/Scanner interface
find field in row <nil> &{name 18}
查询是正常的,只是会多一些 error log
我感觉是 gorm 首先尝试把 JSONType[*User] 当作 Model 来解析, 尝试这个 Model 的每个 Struct Field,然后失败后再完整当作单个的 field 来查询。
但是我也比较困惑。看调用链路 ,这个 field 的 Datatype 肯定是设置了的,是"json" 但是还是走入了这个分支
https://github.com/go-gorm/gorm/blob/532e9cf4ccce927249bcb102c09e4a9093aae4fe/schema/schema.go#L281-L283
if field.DataType == "" && (field.Creatable || field.Updatable || field.Readable) {
if schema.parseRelation(field); schema.err != nil {
return schema, schema.err
再走入了这里 https://github.com/go-gorm/gorm/blob/532e9cf4ccce927249bcb102c09e4a9093aae4fe/schema/relationship.go#L86
目前没有处理 // case guessEmbeddedHas: 所以会有 error log
我看下有什么好的设置可以把 JSONType 当作单个 Field 而不当作 Model 去猜测
我测了下,可以改进,就是会有点 break change
type JSONType[T any] struct {
data T
}
func (j JSONType[T]) GetData() T {
return j.data
}
这样就不会出现上面的 error log 了 晚点我提交一下 , 之前提交的时候没有测试到 cc @jinzhu
the fix MR merged, and no error log anymore,
but your Pluck
usage might wrong.
use Pluck
with JSONType[T]
// ok
var field []datatypes.JSONType[*User]
err = db.Model(&TestTable{}).Limit(1).Order("id DESC").Pluck("info", &field).Error
// find field &{name 18} <nil>
fmt.Println("find field ", field[0].Data(), err)
use Pluck
with JSONSlice[T]
// ok
var parents []datatypes.JSONSlice[*User]
err = db.Model(&TestTable{}).Limit(1).Order("id DESC").Pluck("parent", &parents).Error
fmt.Println("find parents in slice ", err, parents[0], *parents[0][0], *parents[0][1])
they both query ok. see my show case gist https://gist.github.com/alingse/a3187af45d516d591c7a077ed8c739f9