为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
狐的传说 2022-06-06 17:53:39
我有一个从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"}]            }            `)
查看完整描述

1 回答

?
胡说叔叔

TA贡献1804条经验 获得超8个赞

我找不到有关如何实现它的任何信息。经过大量调试后,我能够让它工作,所以发布我的解决方案。


简短的回答:


嵌套切片必须是指针数组


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


 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)

长答案:

  1. 当 DynamicStruct 创建一个Slice of Struct时,它正在创建一个 slice 的指针 reflect.New(reflect.SliceOf(ds.definition)).Interface()。这实际上是一个指向切片的指针。因此,而不是[]*CreditCardsThis 成为*[]*CreditCards

  2. 当 gorm 执行回调以保存关联时,它有一个单独的块用于处理切片,标识的运行时类型不是切片(它是指针)。所以它假设它是结构体并继续将它作为一个简单的结构体来处理。

  3. 但是,当 gorm从 scope 构建字段时,对于非结构字段(如切片),它不会设置字段定义。因此,当 gorm 将前一个切片作为普通结构处理时,它的字段是 Invalid 类型,因为它从未设置过。

所以解决方案是手动创建动态结构作为指针数组,而不是提供的NewSliceOfStructsAPI。


查看完整回答
反对 回复 2022-06-06
  • 1 回答
  • 0 关注
  • 342 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号