Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JSONType field Data: define a valid foreign key for relations or implement the Valuer/Scanner #200

Open
liyuan1125 opened this issue Mar 30, 2023 · 4 comments
Assignees

Comments

@liyuan1125
Copy link

liyuan1125 commented Mar 30, 2023

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
@alingse
Copy link
Contributor

alingse commented Apr 6, 2023

我来看下这个。

@alingse
Copy link
Contributor

alingse commented Apr 6, 2023

@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 去猜测

@alingse
Copy link
Contributor

alingse commented Apr 6, 2023

我测了下,可以改进,就是会有点 break change

type JSONType[T any] struct {
	data T
}

func (j JSONType[T]) GetData() T {
	return j.data
}

这样就不会出现上面的 error log 了
晚点我提交一下 , 之前提交的时候没有测试到 cc @jinzhu

@alingse
Copy link
Contributor

alingse commented Apr 11, 2023

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants