golang中使用gorm进行upsert操作并返回结果。

huangapple go评论113阅读模式
英文:

golang gorm upsert with returning

问题

在我的golang项目中,我使用gorm,并且我需要使用返回子句进行upsert查询,以获取查询中修改后的值。我可以进行upsert操作,但是我无法弄清楚如何将返回子句与其连接起来。表名为counters,代码如下:

  1. te := struct {
  2. Name string //key column
  3. Counter int
  4. }{
  5. Name: "name_to_update",
  6. Counter: 2,
  7. }
  8. DB.
  9. //Model(te).
  10. Clauses(
  11. //clause.Returning{Columns: []clause.Column{{Name: "counter"}}},
  12. clause.OnConflict{
  13. Columns: []clause.Column{{Name: "name"}}, // key column
  14. DoUpdates: clause.Assignments(map[string]interface{}{
  15. "counter": gorm.Expr("counters.counter + ?", 1),
  16. }),
  17. },
  18. ).Create(&te)

生成的SQL查询语句如下:

  1. INSERT INTO "counters" ("counter", "name") VALUES (0, "name_to_update") ON CONFLICT ("name")
  2. DO UPDATE SET "counter"=counters.counter + 1 RETURNING "name" --我需要更新后的counter值,而不是name
  3. 所以计数器已经更新,这是没问题的,但是它返回给我键列(在RETURNING),而我需要计数器的更新值。有什么办法可以解决吗?谢谢
英文:

In my golang project I use gorm and I need to make upsert query with returning clause to get the modified value from the query. I can make upsert, but I cannot figure out how to connect the returnning clause to it. The table name is counters, the code is as follows:

  1. te := struct {
  2. Name string //key column
  3. Counter int
  4. }{
  5. Name: "name_to_update",
  6. Counter: 2,
  7. }
  8. DB.
  9. //Model(te).
  10. Clauses(
  11. //clause.Returning{Columns: []clause.Column{{Name: "counter"}}},
  12. clause.OnConflict{
  13. Columns: []clause.Column{{Name: "name"}}, // key column
  14. DoUpdates: clause.Assignments(map[string]interface{}{
  15. "counter": gorm.Expr("counters.counter + ?", 1),
  16. }),
  17. },
  18. ).Create(&te)

The resulting SQL query is:

  1. INSERT INTO "counters" ("counter", "name") VALUES (0, "name_to_update") ON CONFLICT ("name")
  2. DO UPDATE SET "counter"=counters.counter + 1 RETURNING "name" //I need updated counter value here, not name

So the counter is updated and this is OK, but it returns me the key column (in RETURNING) while I need the updated value of the counter. Any ideas how to fix it? Thank you

答案1

得分: 2

我不确定匿名结构体是否会引发问题。

此外,从你的代码中无法确定表名 "counters" 是从哪里获取的。

我尝试了你的解决方案 - 使用一个专门的结构体来表示模型 - 并且它完全正常工作。

  1. type Counter struct {
  2. Name string `gorm:"primaryKey"`
  3. Counter int
  4. }
  5. ...
  6. counter := Counter{Name: "name_to_update", Counter: 2}
  7. db.
  8. Clauses(
  9. clause.Returning{Columns: []clause.Column{{Name: "counter"}}},
  10. clause.OnConflict{
  11. Columns: []clause.Column{{Name: "name"}},
  12. DoUpdates: clause.Assignments(map[string]interface{}{
  13. "counter": gorm.Expr("counters.counter + ?", 1),
  14. }),
  15. },
  16. ).Create(&counter)
  17. fmt.Println(counter.Counter)

上述代码生成以下 SQL 语句:

  1. INSERT INTO "counters" ("name","counter") VALUES ('name_to_update',10) ON CONFLICT ("name") DO UPDATE SET "counter"=counters.counter + 1 RETURNING "counter"

counter.Counter 的值已经正确更新。

英文:

I'm not sure if the anonymous struct causes an issue.

Also, it's unclear from your code where the table name - "counters" - comes from.

I've tried your solution - but with a dedicated struct for the model - and it works just fine.

  1. type Counter struct {
  2. Name string `gorm:"primaryKey"`
  3. Counter int
  4. }
  5. ...
  6. counter := Counter{Name: "name_to_update", Counter: 2}
  7. db.
  8. Clauses(
  9. clause.Returning{Columns: []clause.Column{{Name: "counter"}}},
  10. clause.OnConflict{
  11. Columns: []clause.Column{{Name: "name"}},
  12. DoUpdates: clause.Assignments(map[string]interface{}{
  13. "counter": gorm.Expr("counters.counter + ?", 1),
  14. }),
  15. },
  16. ).Create(&counter)
  17. fmt.Println(counter.Counter)

The code above generates the following SQL

  1. INSERT INTO "counters" ("name","counter") VALUES ('name_to_update',10) ON CONFLICT ("name") DO UPDATE SET "counter"=counters.counter + 1 RETURNING "counter"

And counter.Counter has correct updated value.

huangapple
  • 本文由 发表于 2022年12月29日 17:04:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/74949143.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定