更新 HasMany 关联失败的 Gorm
Update HasMany Association failing Gorm
当我尝试使用数据更新 Shoppinglist 结构时,出现“没有与 ON CONFLICT 规范 (SQLSTATE 42P10) 匹配的唯一或排除约束”错误
这些是我的结构
type Shoppinglist struct {
Model
ID int `gorm:"primaryKey" json:"id"`
Title string `json:"title"`
Items []Item `json:"items" gorm:"foreignKey:ParentListID;references:ID;"`
Owner string `json:"owner"`
Participants pq.StringArray `gorm:"type:text[]" json:"participants"`
}
type Item struct {
Model
ParentListID int `gorm:"primaryKey" json:"parentListId"`
Title string `json:"title"`
Position int `json:"position"`
Bought bool `json:"bought"`
}
这是我在尝试编辑列表时执行的代码
func EditList(id int, data map[string]interface{}) error {
//https://github.com/go-gorm/gorm/issues/3487
shoppinglist := Shoppinglist{
ID: data["id"].(int),
Title: data["title"].(string),
Items: data["items"].([]Item),
Owner: data["owner"].(string),
Participants: data["participants"].([]string),
}
if err := db.Session(&gorm.Session{FullSaveAssociations: true}).Where("id = ?", id).Updates(&shoppinglist).Error; err != nil {
return err
}
return nil
}
这是我执行 EditList 的地方,也是我设置所有值以传递 nito 地图的地方:
type Shoppinglist struct {
ID int
Title string
Items []models.Item
Owner string
Participants []string
PageNum int
PageSize int
}
func (s *Shoppinglist) Edit() error {
shoppinglist := map[string]interface{}{
"id": s.ID,
"title": s.Title,
"items": s.Items,
"owner": s.Owner,
"participants": s.Participants,
}
return models.EditList(s.ID, shoppinglist)
}
之前我只是使用 []string 而不是 []Item 并且它工作得很好。现在除了 []Item
之外的所有内容都会更新
这些是 SQL 执行的查询:
UPDATE "shoppinglists" SET "modified_on"=1628251977096,"title"='kjhdsfgnb',"owner"='janburzinski1@gmail.com',"participants"='{}' WHERE id = 517687 AND "id" = 517687
INSERT INTO "items" ("created_on","modified_on","deleted_at","title","position","bought","parent_list_id") VALUES (1628251977,1628251977116,NULL,'dfkjhgndfjkg',1,false,517687),(1628251977,1628251977116,NULL,'dfgh123',2,true,517687) ON CONFLICT ("parent_list_id") DO UPDATE SET "created_on"="excluded"."created_on","modified_on"="excluded"."modified_on","deleted_at"="excluded"."deleted_at","title"="excluded"."title","position"="excluded"."position","bought"="excluded"."bought" RETURNING "parent_list_id"
我真的很想知道如何在 Gorm 中更新关系,或者为什么这不起作用,因为我一直在查看 Github 和 Whosebug 上的所有关联问题,但没有找到对我有用的答案。
我在这里看到的第一个问题是您的项目没有 ID,而是使用 ParentListID 作为主键。这意味着您只能为每个父级拥有一个项目,这违背了拥有数组的目的。
为项目创建一个 ID 字段(用作主键),如果您的方法仍有问题,请更新问题。
PS:本可以在评论中留下这个,但不能。
我只需要将 * 添加到 []Item 并解决主键问题并删除引用。
type Shoppinglist struct {
Model
ID int `gorm:"primaryKey" json:"id"`
Title string `json:"title"`
Items []*Item `json:"items" gorm:"foreignKey:ParentListID;"`
Owner string `json:"owner"`
Participants pq.StringArray `gorm:"type:text[]" json:"participants"`
}
type Item struct {
Model
ID int `gorm:"primaryKey" json:"id"`
ParentListID int `json:"parentListId"`
ItemID int `json:"itemId"`
Title string `json:"title"`
Position int `json:"position"`
Bought bool `json:"bought" gorm:"default:false"`
}
当我尝试使用数据更新 Shoppinglist 结构时,出现“没有与 ON CONFLICT 规范 (SQLSTATE 42P10) 匹配的唯一或排除约束”错误
这些是我的结构
type Shoppinglist struct {
Model
ID int `gorm:"primaryKey" json:"id"`
Title string `json:"title"`
Items []Item `json:"items" gorm:"foreignKey:ParentListID;references:ID;"`
Owner string `json:"owner"`
Participants pq.StringArray `gorm:"type:text[]" json:"participants"`
}
type Item struct {
Model
ParentListID int `gorm:"primaryKey" json:"parentListId"`
Title string `json:"title"`
Position int `json:"position"`
Bought bool `json:"bought"`
}
这是我在尝试编辑列表时执行的代码
func EditList(id int, data map[string]interface{}) error {
//https://github.com/go-gorm/gorm/issues/3487
shoppinglist := Shoppinglist{
ID: data["id"].(int),
Title: data["title"].(string),
Items: data["items"].([]Item),
Owner: data["owner"].(string),
Participants: data["participants"].([]string),
}
if err := db.Session(&gorm.Session{FullSaveAssociations: true}).Where("id = ?", id).Updates(&shoppinglist).Error; err != nil {
return err
}
return nil
}
这是我执行 EditList 的地方,也是我设置所有值以传递 nito 地图的地方:
type Shoppinglist struct {
ID int
Title string
Items []models.Item
Owner string
Participants []string
PageNum int
PageSize int
}
func (s *Shoppinglist) Edit() error {
shoppinglist := map[string]interface{}{
"id": s.ID,
"title": s.Title,
"items": s.Items,
"owner": s.Owner,
"participants": s.Participants,
}
return models.EditList(s.ID, shoppinglist)
}
之前我只是使用 []string 而不是 []Item 并且它工作得很好。现在除了 []Item
之外的所有内容都会更新这些是 SQL 执行的查询:
UPDATE "shoppinglists" SET "modified_on"=1628251977096,"title"='kjhdsfgnb',"owner"='janburzinski1@gmail.com',"participants"='{}' WHERE id = 517687 AND "id" = 517687
INSERT INTO "items" ("created_on","modified_on","deleted_at","title","position","bought","parent_list_id") VALUES (1628251977,1628251977116,NULL,'dfkjhgndfjkg',1,false,517687),(1628251977,1628251977116,NULL,'dfgh123',2,true,517687) ON CONFLICT ("parent_list_id") DO UPDATE SET "created_on"="excluded"."created_on","modified_on"="excluded"."modified_on","deleted_at"="excluded"."deleted_at","title"="excluded"."title","position"="excluded"."position","bought"="excluded"."bought" RETURNING "parent_list_id"
我真的很想知道如何在 Gorm 中更新关系,或者为什么这不起作用,因为我一直在查看 Github 和 Whosebug 上的所有关联问题,但没有找到对我有用的答案。
我在这里看到的第一个问题是您的项目没有 ID,而是使用 ParentListID 作为主键。这意味着您只能为每个父级拥有一个项目,这违背了拥有数组的目的。
为项目创建一个 ID 字段(用作主键),如果您的方法仍有问题,请更新问题。
PS:本可以在评论中留下这个,但不能。
我只需要将 * 添加到 []Item 并解决主键问题并删除引用。
type Shoppinglist struct {
Model
ID int `gorm:"primaryKey" json:"id"`
Title string `json:"title"`
Items []*Item `json:"items" gorm:"foreignKey:ParentListID;"`
Owner string `json:"owner"`
Participants pq.StringArray `gorm:"type:text[]" json:"participants"`
}
type Item struct {
Model
ID int `gorm:"primaryKey" json:"id"`
ParentListID int `json:"parentListId"`
ItemID int `json:"itemId"`
Title string `json:"title"`
Position int `json:"position"`
Bought bool `json:"bought" gorm:"default:false"`
}