gpt4 book ai didi

database - GORM 中的复杂更新

转载 作者:行者123 更新时间:2023-12-01 22:13:19 33 4
gpt4 key购买 nike

我在 GORM 中有一个以 Postgres 作为数据库的模型。模型是这样的

type Country struct {
gorm.Model
Name string
Population int64
Regions []Region
}

type Region struct {
gorm.Model
Name string
Cities []City
CountryID uint `sql:"type:bigint REFERENCES countries(id) ON DELETE CASCADE" json:"-"`
}

type City struct {
gorm.Model
Name string
Comment string
RegionID uint `sql:"type:bigint REFERENCES regions(id) ON DELETE CASCADE" json:"-"`
}

当我从模型创建新记录时,我调用 create 函数
db.Create(&menu)

现在,我正在尝试更新模型,但遇到了一些问题。
如果我调用这个
err = db.Debug().Where("id = ?", countryId).Updates(&country).Error

我有一个错误,模型未在数据库中更新
更新:
错误是

(C:/source/go/gorm/country.go:100)
[2020-06-06 02:37:59] sql: converting argument $4 type: unsupported type []main.Region, a slice of struct

(C:/source/go/gorm/country.go:100)
[2020-06-06 02:37:59] [0.00ms] UPDATE "" SET "created_at" = '2020-06-06 00:37:50', "id" = 1, "name" = 'New Name', "regions" = '[{{1 2020-06-06 00:37:50.450497 +0000 UTC 2020-06-06 00:37:50.450497 +0000 UTC <nil>} Region 1 [{{1 2020-06-06 00:37:50.465029 +0000 UTC 2020-06-06 00:37:50.465029 +0000 UTC <nil>} City 1 1}] 1} {{0 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC <nil>} Region 2 updated [{{0 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC <nil>} City 2 updated 0}] 0}]', "updated_at" = '2020-06-06 00:37:50' WHERE (id = 1)
[0 rows affected or returned ]

如果我跑
err = db.Debug().Model(&country).Association("Regions").Replace(country.Regions).Error

地区和城市模型在数据库中更新,但国家模型未更新。
除此之外,对于更新删除元素期间的区域模型,CountryID 为 null,但城市模型不会更新其 RegionID 以取消引用。

如何更新这样的完整模型?

更新:

我不知道如何更新完整的 Country 模型。
这是执行的完整查询。
Create Tables

(C:/source/go/gorm/country.go:35)
[2020-06-06 01:33:29] [36;1m[20.02ms] CREATE TABLE "countries" ("id" serial,"created_at" timestamp with time zone,"updated_at" timestamp with time zone,"deleted_at" timestamp with time zone,"name" text,"population" bigint , PRIMARY KEY ("id"))
[36;31m[0 rows affected or returned ]

(C:/source/go/gorm/country.go:35)
[2020-06-06 01:33:29] [36;1m[16.00ms] CREATE INDEX idx_countries_deleted_at ON "countries"(deleted_at)
[36;31m[0 rows affected or returned ]

(C:/source/go/gorm/country.go:36)
[2020-06-06 01:33:29] [36;1m[28.99ms] CREATE TABLE "regions" ("id" serial,"created_at" timestamp with time zone,"updated_at" timestamp with time zone,"deleted_at" timestamp with time zone,"name" text,"country_id" bigint REFERENCES countries(id) ON DELETE CASCADE , PRIMARY KEY ("id"))
[36;31m[0 rows affected or returned ]

(C:/source/go/gorm/country.go:36)
[2020-06-06 01:33:29] [36;1m[11.99ms] CREATE INDEX idx_regions_deleted_at ON "regions"(deleted_at)
[36;31m[0 rows affected or returned ]

(C:/source/go/gorm/country.go:37)
[2020-06-06 01:33:29] [36;1m[18.99ms] CREATE TABLE "cities" ("id" serial,"created_at" timestamp with time zone,"updated_at" timestamp with time zone,"deleted_at" timestamp with time zone,"name" text,"comment" text,"region_id" bigint REFERENCES regions(id) ON DELETE CASCADE , PRIMARY KEY ("id"))
[36;31m[0 rows affected or returned ]

(C:/source/go/gorm/country.go:37)
[2020-06-06 01:33:29] [36;1m[32.00ms] CREATE INDEX idx_cities_deleted_at ON "cities"(deleted_at)
[36;31m[0 rows affected or returned ]
Add Country Model

(C:/source/go/gorm/country.go:64)
[2020-06-06 01:33:32] [36;1m[3.99ms] INSERT INTO "countries" ("created_at","updated_at","deleted_at","name","population") VALUES ('2020-06-06 01:33:32','2020-06-06 01:33:32',NULL,'Country 1',0) RETURNING "countries"."id"
[36;31m[1 rows affected or returned ]

(C:/source/go/gorm/country.go:64)
[2020-06-06 01:33:32] [36;1m[4.00ms] INSERT INTO "regions" ("created_at","updated_at","deleted_at","name","country_id") VALUES ('2020-06-06 01:33:32','2020-06-06 01:33:32',NULL,'Region 1',1) RETURNING "regions"."id"
[36;31m[1 rows affected or returned ]

(C:/source/go/gorm/country.go:64)
[2020-06-06 01:33:32] [36;1m[3.00ms] INSERT INTO "cities" ("created_at","updated_at","deleted_at","name","comment","region_id") VALUES ('2020-06-06 01:33:32','2020-06-06 01:33:32',NULL,'City 1','',1) RETURNING "cities"."id"
[36;31m[1 rows affected or returned ]

(C:/source/go/gorm/country.go:64)
[2020-06-06 01:33:32] [36;1m[4.00ms] INSERT INTO "regions" ("created_at","updated_at","deleted_at","name","country_id") VALUES ('2020-06-06 01:33:32','2020-06-06 01:33:32',NULL,'Region 2',1) RETURNING "regions"."id"
[36;31m[1 rows affected or returned ]

(C:/source/go/gorm/country.go:64)
[2020-06-06 01:33:32] [36;1m[3.83ms] INSERT INTO "cities" ("created_at","updated_at","deleted_at","name","comment","region_id") VALUES ('2020-06-06 01:33:32','2020-06-06 01:33:32',NULL,'City 2','',2) RETURNING "cities"."id"
[36;31m[1 rows affected or returned ]
Update Country Model

(C:/source/go/gorm/country.go:75)
[2020-06-06 01:33:39] [36;1m[3.99ms] SELECT * FROM "countries" WHERE "countries"."deleted_at" IS NULL AND ((id = 1))
[36;31m[1 rows affected or returned ]

(C:/source/go/gorm/country.go:75)
[2020-06-06 01:33:39] [36;1m[4.00ms] SELECT * FROM "regions" WHERE "regions"."deleted_at" IS NULL AND (("country_id" IN (1)))
[36;31m[2 rows affected or returned ]

(C:/source/go/gorm/country.go:75)
[2020-06-06 01:33:39] [36;1m[3.00ms] SELECT * FROM "cities" WHERE "cities"."deleted_at" IS NULL AND (("region_id" IN (1,2)))
[36;31m[2 rows affected or returned ]
{{1 2020-06-05 23:33:32.660156 +0000 UTC 2020-06-05 23:33:32.660156 +0000 UTC <nil>} Country 1 0 [{{1 2020-06-05 23:33:32.664151 +0000 UTC 2020-06-05 23:33:32.664151 +0000 UTC <nil>} Region 1 [{{1 2020-06-05 23:33:32.668156 +0000 UTC 2020-06-05 23:33:32.668156 +0000 UTC <nil>} City 1 1}] 1} {{2 2020-06-05 23:33:32.672155 +0000 UTC 2020-06-05 23:33:32.672155 +0000 UTC <nil>} Region 2 [{{2 2020-06-05 23:33:32.676156 +0000 UTC 2020-06-05 23:33:32.676156 +0000 UTC <nil>} City 2 2}] 1}]}

(C:/source/go/gorm/country.go:99)
[2020-06-06 01:33:39] [36;1m[3.00ms] UPDATE "regions" SET "created_at" = '2020-06-05 23:33:32', "updated_at" = '2020-06-06 01:33:39', "deleted_at" = NULL, "name" = 'Region 1', "country_id" = 1 WHERE "regions"."deleted_at" IS NULL AND "regions"."id" = 1
[36;31m[1 rows affected or returned ]

()
[2020-06-06 01:33:39] [36;1m[6.00ms] UPDATE "cities" SET "created_at" = '2020-06-05 23:33:32', "updated_at" = '2020-06-06 01:33:39', "deleted_at" = NULL, "name" = 'City 1', "comment" = '', "region_id" = 1 WHERE "cities"."deleted_at" IS NULL AND "cities"."id" = 1
[36;31m[1 rows affected or returned ]

(C:/source/go/gorm/country.go:99)
[2020-06-06 01:33:39] [36;1m[4.00ms] SELECT * FROM "countries" WHERE "countries"."deleted_at" IS NULL AND "countries"."id" = 1 ORDER BY "countries"."id" ASC LIMIT 1
[36;31m[1 rows affected or returned ]

(C:/source/go/gorm/country.go:99)
[2020-06-06 01:33:39] [36;1m[3.00ms] UPDATE "regions" SET "created_at" = '2020-06-05 23:33:32', "updated_at" = '2020-06-06 01:33:39', "deleted_at" = NULL, "name" = 'Region 1', "country_id" = 1 WHERE "regions"."deleted_at" IS NULL AND "regions"."id" = 1
[36;31m[1 rows affected or returned ]

()
[2020-06-06 01:33:39] [36;1m[4.99ms] UPDATE "cities" SET "created_at" = '2020-06-05 23:33:32', "updated_at" = '2020-06-06 01:33:39', "deleted_at" = NULL, "name" = 'City 1', "comment" = '', "region_id" = 1 WHERE "cities"."deleted_at" IS NULL AND "cities"."id" = 1
[36;31m[1 rows affected or returned ]

(C:/source/go/gorm/country.go:99)
[2020-06-06 01:33:39] [36;1m[4.00ms] INSERT INTO "regions" ("created_at","updated_at","deleted_at","name","country_id") VALUES ('2020-06-06 01:33:39','2020-06-06 01:33:39',NULL,'Region 2 updated',1) RETURNING "regions"."id"
[36;31m[1 rows affected or returned ]

()
[2020-06-06 01:33:39] [36;1m[3.99ms] INSERT INTO "cities" ("created_at","updated_at","deleted_at","name","comment","region_id") VALUES ('2020-06-06 01:33:39','2020-06-06 01:33:39',NULL,'City 2 updated','',3) RETURNING "cities"."id"
[36;31m[1 rows affected or returned ]

(C:/source/go/gorm/country.go:99)
[2020-06-06 01:33:39] [36;1m[3.00ms] SELECT * FROM "countries" WHERE "countries"."deleted_at" IS NULL AND "countries"."id" = 1 ORDER BY "countries"."id" ASC LIMIT 1
[36;31m[1 rows affected or returned ]

(C:/source/go/gorm/country.go:99)
[2020-06-06 01:33:39] [36;1m[3.99ms] UPDATE "regions" SET "country_id" = NULL WHERE "regions"."deleted_at" IS NULL AND (("id" NOT IN (1,3)) AND ("country_id" = 1))
[36;31m[1 rows affected or returned ]


最佳答案

要更新现有数据,您可以获取第一个预加载子

var country Country
db.Preload("Regions").Preload("Regions.Cities").First(&country, 1)

然后您可以更新数据并添加新数据,例如
country.Regions[0].Cities[0].Name = "Dhaka City 1"
country.Regions[0].Name = "Dhaka Region 1"
country.Regions[1].Cities = append(country.Regions[1].Cities, City{Name: "Dhaka City 2"})

现在将更新的数据保存在数据库中
db.Save(&country)

如果您只想添加新的子数据,您也可以避免 Preload。
db.First(&country, 8)
country.Regions = append(country.Regions, Region{Name: "Dhaka Region 3"})
db.Save(&country)

默认情况下 gorm association_autoupdate标志设置为 true ,所以它是自动保存关联。
err = db.Debug().Model(&country).Association("Regions").Replace(country.Regions).Error

Replace 仅将关联方式替换为其他。如果您不提供任何信息,它只会删除与 Country 的当前关联。这里。而且只有 Regions不是 child 城。

Gorm 不支持更新时的任何删除操作。它仅用于添加或更新现有数据。
Gorm 模型默认使用软删除。如果您以这种方式删除区域,它将更新 deleted_at场数据。并且在查询时它总是过滤掉已删除的数据。
db.Delete(county.Regions)

而且它不会软删除 City,你必须这样做。
db.Delete(region.Cities)

工作代码示例 here

关于database - GORM 中的复杂更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62220553/

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