gpt4 book ai didi

go - 使用 slice 的动态结构(包含外键)和go-gorm将数据插入db

转载 作者:行者123 更新时间:2023-12-01 21:13:25 32 4
gpt4 key购买 nike

我从Ompluscator创建了一个动态结构,它包含一个带有外键引用的嵌套结构(结构片)。

父表(User Table)和子表(Credit Card)成功创建。甚至可以成功插入到用户表中,但是稍后在处理field value not valid表条目时最终会出现credit_card错误。

这是完整的代码:

creditCardStruct := dynamicstruct.NewStruct().
AddField("Bank", "", `protobuf:"bytes,1,opt,name=number,proto3" json:"bank,omitempty" gorm:"column:bank;not null"`).
AddField("Number", "", `protobuf:"bytes,1,opt,name=number,proto3" json:"number,omitempty" gorm:"column:number;not null;size:16;primary_key"`).
AddField("Cvv", "", `protobuf:"bytes,2,opt,name=cvv,proto3" json:"cvv,omitempty" gorm:"column:cvv;not null;size:5" skyflow:"only4digits"`).
//AddField("Expiry", timeNow, `protobuf:"bytes,3,opt,name=expiry,proto3" json:"expiry,omitempty" gorm:"column:expiry;type:timestamp;not null;"`).
AddField("Name", "", `protobuf:"bytes,1,opt,name=number,proto3" json:"name,omitempty" gorm:"column:name;not null"`).
AddField("ProfileID", "", `protobuf:"bytes,5,opt,name=userName,proto3" json:"profile_id,omitempty" sql:"type:string REFERENCES user_normalized1(profile_id)" gorm:"column:profile_id;not null;primary_key"`).
Build().NewSliceOfStructs()

userInstance := dynamicstruct.NewStruct().
AddField("ProfileID", "", `protobuf:"bytes,1,opt,name=number,proto3" json:"profile_id,omitempty" gorm:"column:profile_id;unique;not null;unique_index;primary_key"`).
AddField("CreditCards", creditCardStruct, `protobuf:"bytes,1,opt,name=number,proto3" json:"credit_cards,omitempty" gorm:"foreignkey:ProfileID;association_foreignkey:ProfileID"`).
Build().
New()

db.Table("user_normalized1").AutoMigrate(userInstance)
db.Table("credit_card1").AutoMigrate(creditCardStruct)

data := []byte(`
{
"profile_id":"123",
"first_name": "fname",
"last_name": "lname",
"some_text": "dummy"

,"credit_cards": [{"bank":"bank1", "cvv":"123", "name":"fname", "number":"nlabla1"},{"bank":"bank2", "cvv":"1234", "name":"lname", "number":"nlabla2"}]
}
`)

err := json.Unmarshal(data, &userInstance)
if err != nil {
log.Fatal(err)
}
data, err = json.Marshal(userInstance)
if err != nil {
log.Fatal(err)
}

fmt.Println(string(data))

db.Table("user_normalized1").Create(userInstance)

这是日志:
[2020-06-04 16:03:25]  [8.93ms]  CREATE TABLE "user_normalized1" ("profile_id" text NOT NULL UNIQUE , PRIMARY KEY ("profile_id"))  
[0 rows affected or returned ]

[2020-06-04 16:03:25] [106.26ms] CREATE UNIQUE INDEX uix_user_normalized1_profile_id ON "user_normalized1"(profile_id)
[0 rows affected or returned ]

[2020-06-04 16:03:25] [44.12ms] CREATE TABLE "credit_card1" ("profile_id" string REFERENCES user_normalized1(profile_id) NOT NULL,"bank" text NOT NULL,"number" varchar(16) NOT NULL,"cvv" varchar(5) NOT NULL,"name" text NOT NULL , PRIMARY KEY ("profile_id","number"))
[0 rows affected or returned ]
{"profile_id":"123","credit_cards":[{"bank":"bank1","number":"nlabla1","cvv":"123","name":"fname"},{"bank":"bank2","number":"nlabla2","cvv":"1234","name":"lname"}]}
[2020-06-04 16:03:25] [1.50ms] INSERT INTO "user_normalized1" ("profile_id") VALUES ('123') RETURNING "user_normalized1"."profile_id"
[1 rows affected or returned ]
[2020-06-04 16:03:25] field value not valid

最佳答案

我找不到有关如何实现的任何信息。经过大量调试,我能够使其正常运行,因此发布了我的解决方案。

简答:

嵌套 slice 必须为指针数组

以此方式定义您的嵌套/子结构

 creditCardStruct := dynamicstruct.NewStruct().
AddField("Bank", "", `protobuf:"bytes,1,opt,name=number,proto3" json:"bank,omitempty" gorm:"column:bank;not null"`).
AddField("Number", "", `protobuf:"bytes,1,opt,name=number,proto3" json:"number,omitempty" gorm:"column:number;not null;size:16;primary_key"`).
AddField("Cvv", "", `protobuf:"bytes,2,opt,name=cvv,proto3" json:"cvv,omitempty" gorm:"column:cvv;not null;size:5" skyflow:"only4digits"`).
//AddField("Expiry", timeNow, `protobuf:"bytes,3,opt,name=expiry,proto3" json:"expiry,omitempty" gorm:"column:expiry;type:timestamp;not null;"`).
AddField("Name", "", `protobuf:"bytes,1,opt,name=number,proto3" json:"name,omitempty" gorm:"column:name;not null"`).
AddField("ProfileID", "", `protobuf:"bytes,5,opt,name=userName,proto3" json:"profile_id,omitempty" sql:"type:string REFERENCES user_normalized1(profile_id)" gorm:"column:profile_id;not null;primary_key"`).
Build().New()

creditCardArrayInstance := reflect.New(reflect.SliceOf(reflect.TypeOf(creditCardStruct))).Elem().Interface()

userInstance := dynamicstruct.NewStruct().
AddField("ProfileID", "", `protobuf:"bytes,1,opt,name=number,proto3" json:"profile_id,omitempty" gorm:"column:profile_id;unique;not null;unique_index;primary_key"`).
AddField("CreditCards", creditCardArrayInstance, `protobuf:"bytes,1,opt,name=number,proto3" json:"credit_cards,omitempty" gorm:"foreignkey:ProfileID;association_foreignkey:ProfileID"`).
Build().
New()

db.Table("user_normalized1").AutoMigrate(userInstance)
db.Table("credit_card1").AutoMigrate(creditCardStruct)

详细答案:
  • 当DynamicStruct创建Slice of Struct时,它正在创建 slice 的指针reflect.New(reflect.SliceOf(ds.definition)).Interface()
    实际上,这实际上是指向 slice 的指针。所以代替了[]*CreditCards这变成了*[]*CreditCards
  • 当gorm执行callback to save Associations时,它有一个单独的块用于处理片,所标识的运行时类型不是片(它是指针)。因此,它假定它是结构,然后将其作为简单结构进行处理。
  • 但是,当gorm构建fields from scope时,对于非结构字段(例如 slice ),它不会设置字段定义。因此,当gorm将前一个 slice 作为普通结构处理时,其字段属于Invalid类型,因为它从未设置过。

  • 因此,解决方案是将动态结构手动创建为指针数组,而不是提供的NewSliceOfStructs API。

    关于go - 使用 slice 的动态结构(包含外键)和go-gorm将数据插入db,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62193214/

    32 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com