简体   繁体   English

表上插入或更新的 GORM 错误违反外键约束

[英]GORM Error on insert or update on table violates foreign key constraint

I have the following set of GORM models, with 2 orders of one-to-many relations:我有以下一组 GORM 模型,具有 2 个一对多关系的顺序:

type Order struct {
    ID       string  `gorm:"column:id"`
    ClientID string  `gorm:"primaryKey;column:client_id"`
    Name     string  `gorm:"column:name"`
    Albums   []Album `gorm:"foreignKey:RequestClientID"`
}

type Album struct {
    AlbumID         string    `gorm:"primaryKey;column:album_id"`
    RequestClientID string    `gorm:"foreignKey:ClientID;column:request_client_id"`
    Pictures        []Picture `gorm:"foreignKey:AlbumID"`
}

type Picture struct {
    PictureID   string `gorm:"primaryKey;column:picture_id"`
    AlbumID     string `gorm:"foreignKey:AlbumID;column:album_id"`
    Description string `gorm:"column:description"`
}

When I attempt to insert data as follows, I get the error pq: insert or update on table "albums" violates foreign key constraint "fk_orders_albums" .当我尝试按如下方式插入数据时,我收到错误pq: insert or update on table "albums" violates foreign key constraint "fk_orders_albums"

test := Order{
    ID:       "abc",
    ClientID: "client1",
    Name:     "Roy",
    Albums: []Album{
        {
            AlbumID: "al_1",
            Pictures: []Picture{
                {
                    PictureID:   "pic_1",
                    Description: "test pic",
                },
            },
        },
    },
}

gormDB.Save(&test)

I followed the solution on this similar question, but can't seem to get it to work: Golang: Gorm Error on insert or update on table violates foreign key contraint我遵循了这个类似问题的解决方案,但似乎无法让它工作: Golang: Gorm Error on insert or update on table违反了外键约束

Based on your entity model, Your schema would be like this:根据您的实体 model,您的架构将如下所示:

  • Orders table is parent table, didn't depend to any table Orders 表是父表,不依赖于任何表
  • Albums table has foreign key request_client_id which refer to orders table column client_id Albums 表有外键 request_client_id 引用订单表列 client_id
  • Picture table has foreign key album_id which is refer to albums table column album_id图片表有外键album_id,指的是相册表列album_id

Based on my exploration in gorm documentation here , object in struct will be examine as first association.根据我此处的 gorm 文档中的探索,结构中的 object 将作为第一个关联进行检查。 so, your struct will execute insert to albums first which it violate foreign key schema (expect: insert to orders table should be executed before albums).因此,您的结构将首先执行插入到albums中,这违反了外键模式(期望:插入到订单表应该在专辑之前执行)。

But if you want to force using your schema, you can use gorm Association feature.但是如果你想强制使用你的模式,你可以使用 gorm 关联功能。 Here is the idea of using Association:这是使用关联的想法:

Expected Query in high level:高级别的预期查询:

  • Insert to orders table插入订单表
  • Insert to albums table插入到相册表
  • Insert to pictures table插入图片表

Association Ideas:协会理念:

  • Let Albums field value in Orders struct empty让 Orders 结构中的 Albums 字段值为空
  • Append Association Albums to Orders model Append 关联相册到订单 model
  • Since there have another association in Albums, use configuration FullSaveAssociation由于相册中有另一个关联,因此使用配置 FullSaveAssociation

Here is the following code:这是以下代码:

picture := []Picture{
    {
        PictureID:   "pic_1",
        Description: "test pic",
    },
}
albums := []Album{
    {
        ID:              "al_1",
        Pictures:        picture,
        RequestClientID: "",
    },
}
orders := Order{
    ID:       "abc",
    ClientID: "client1",
    Name:     "Roy",
}
if err := gormDB.Save(orders).Error; err != nil {
    return
}
if err := gormDB.Session(&gorm.Session{FullSaveAssociations: true}).Model(&orders).Association("Albums").Append(albums); err != nil {
    return
}

Full code could be found here :完整的代码可以在这里找到:

Came across the solution I was looking for while looking into the great answer @giyuu provided.在查看@giyuu 提供的出色答案时遇到了我正在寻找的解决方案。 Since I had not saved the item before, I needed to use GORM's Create method:由于我之前没有保存项目,所以我需要使用 GORM 的Create方法:

err = gormDB.Create(&test).Error

Then, when I want to perform an update on any of these values, I use the Save method, with FullSaveAssociations enabled:然后,当我想对这些值中的任何一个执行更新时,我使用Save方法,并启用FullSaveAssociations

err = gormDB.Session(&gorm.Session{FullSaveAssociations: true}).Save(&test).Error

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM