AutIncrement在使用GORM时对我不起作用。

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

AutIncrement doesnt work for me with GORM

问题

当我运行以下代码时,我一遍又一遍地收到这个错误消息:

/Sites/importer/import.go:142 Error 1062: Duplicate entry '112' for key 'products.PRIMARY'

我尝试过使用gorm.Model和不使用它,但都没有帮助。在INSERT语句中生成的ID不会改变。

谢谢。

Adrian

  1. package main
  2. import (
  3. "encoding/csv"
  4. "log"
  5. "gorm.io/datatypes"
  6. "gorm.io/driver/mysql"
  7. "gorm.io/gorm"
  8. "os"
  9. "strconv"
  10. )
  11. var merchant_feeds []MerchantFeed
  12. var merchant_csv_mappings []MerchantCsvMapping
  13. type MerchantFeed struct {
  14. // gorm.Model
  15. ID int `gorm:"primary_key"`
  16. MerchantID int
  17. }
  18. type MerchantCsvMapping struct {
  19. // gorm.Model
  20. ID int `gorm:"primary_key"`
  21. MerchantId int
  22. Name string
  23. ProductNo string
  24. PriceOld string
  25. Ean string
  26. Price string
  27. Category int
  28. DeepLink string
  29. ShortDescription string
  30. LongDescription string
  31. BrandMerchant int
  32. MerchantImageURL string
  33. AlternateImage string
  34. GalleryImage int
  35. GalleryImage2 int
  36. GalleryImage3 int
  37. GalleryImage4 int
  38. DeliveryTime string
  39. DeliveryCost string
  40. }
  41. type Product struct {
  42. // gorm.Model
  43. ID int `gorm:"primary_key"`
  44. MerchantId int
  45. Name string
  46. Slug string
  47. ProductNo string
  48. PriceOld string
  49. Tags datatypes.JSON
  50. Price string
  51. Discount int
  52. Ean string
  53. DeepLink string
  54. ShortDescription string
  55. LongDescription string
  56. MerchantImageUrl string
  57. AlternateImage string
  58. DeliveryTime string
  59. DeliveryCost string
  60. }
  61. func main() {
  62. db, err := gorm.Open(mysql.Open("root@tcp(127.0.0.1:3306)/myshop?parseTime=true"), &gorm.Config{})
  63. if err != nil {
  64. panic("failed to connect database")
  65. }
  66. db.Find(&merchant_feeds, 7)
  67. for _, feed := range merchant_feeds {
  68. db.Where("merchant_id = ?", feed.MerchantID).Find(&merchant_csv_mappings)
  69. importProducts(feed.MerchantID, feed.ID, merchant_csv_mappings, db)
  70. }
  71. }
  72. func importProducts(MerchantID int, FeedID int, CsvMapping []MerchantCsvMapping, db *gorm.DB) {
  73. path := strconv.Itoa(MerchantID) + "-" + strconv.Itoa(FeedID) + "-feed.csv"
  74. products := readCsvFile(path)
  75. i := 0
  76. var product Product
  77. for _, p := range products {
  78. if i == 0 {
  79. i++
  80. continue
  81. }
  82. mapping := CsvMapping[0]
  83. product.MerchantId = MerchantID
  84. idx2, _ := strconv.Atoi(string(mapping.Name))
  85. product.Name = p[idx2]
  86. idx3, _ := strconv.Atoi(string(mapping.ProductNo))
  87. product.ProductNo = p[idx3]
  88. idx4, _ := strconv.Atoi(string(mapping.PriceOld))
  89. product.PriceOld = p[idx4]
  90. idx5, _ := strconv.Atoi(string(mapping.Price))
  91. product.Price = p[idx5]
  92. idx6, _ := strconv.Atoi(string(mapping.Ean))
  93. product.Ean = p[idx6]
  94. idx7, _ := strconv.Atoi(string(mapping.DeepLink))
  95. product.DeepLink = p[idx7]
  96. idx8, _ := strconv.Atoi(string(mapping.ShortDescription))
  97. product.ShortDescription = p[idx8]
  98. idx9, _ := strconv.Atoi(string(mapping.LongDescription))
  99. product.LongDescription = p[idx9]
  100. idx10, _ := strconv.Atoi(string(mapping.MerchantImageURL))
  101. product.MerchantImageUrl = p[idx10]
  102. idx11, _ := strconv.Atoi(string(mapping.AlternateImage))
  103. product.AlternateImage = p[idx11]
  104. idx12, _ := strconv.Atoi(string(mapping.DeliveryTime))
  105. product.DeliveryTime = p[idx12]
  106. idx13, _ := strconv.Atoi(string(mapping.DeliveryCost))
  107. product.DeliveryCost = p[idx13]
  108. db.Create(&product)
  109. log.Println(product.ID)
  110. }
  111. }
  112. func readCsvFile(filePath string) [][]string {
  113. f, err := os.Open(filePath)
  114. if err != nil {
  115. log.Fatal("Unable to read input file "+filePath, err)
  116. }
  117. defer f.Close()
  118. csvReader := csv.NewReader(f)
  119. records, err := csvReader.ReadAll()
  120. if err != nil {
  121. log.Fatal("Unable to parse file as CSV for "+filePath, err)
  122. }
  123. return records
  124. }
英文:

When i run the following code, i get this error message over and over

/Sites/importer/import.go:142 Error 1062: Duplicate entry '112' for key 'products.PRIMARY'

I tried with gorm.Model and without. Nothing helped.
The generated ID inside the INSERT statement dont change.

Regards

Adrian

  1. import (
  2. "encoding/csv"
  3. "log"
  4. "gorm.io/datatypes"
  5. "gorm.io/driver/mysql"
  6. "gorm.io/gorm"
  7. "os"
  8. "strconv"
  9. )
  10. var merchant_feeds []MerchantFeed
  11. var merchant_csv_mappings []MerchantCsvMapping
  12. type MerchantFeed struct {
  13. // gorm.Model
  14. ID int `gorm:"primary_key"`
  15. MerchantID int
  16. }
  17. type MerchantCsvMapping struct {
  18. // gorm.Model
  19. ID int `gorm:"primary_key"`
  20. MerchantId int
  21. Name string
  22. ProductNo string
  23. PriceOld string
  24. Ean string
  25. Price string
  26. Category int
  27. DeepLink string
  28. ShortDescription string
  29. LongDescription string
  30. BrandMerchant int
  31. MerchantImageURL string
  32. AlternateImage string
  33. GalleryImage int
  34. GalleryImage2 int
  35. GalleryImage3 int
  36. GalleryImage4 int
  37. DeliveryTime string
  38. DeliveryCost string
  39. }
  40. type Product struct {
  41. // gorm.Model
  42. ID int `gorm:"primary_key"`
  43. MerchantId int
  44. Name string
  45. Slug string
  46. ProductNo string
  47. PriceOld string
  48. Tags datatypes.JSON
  49. Price string
  50. Discount int
  51. Ean string
  52. DeepLink string
  53. ShortDescription string
  54. LongDescription string
  55. MerchantImageUrl string
  56. AlternateImage string
  57. DeliveryTime string
  58. DeliveryCost string
  59. }
  60. func main() {
  61. db, err := gorm.Open(mysql.Open("root@tcp(127.0.0.1:3306)/myshop?parseTime=true"), &gorm.Config{})
  62. if err != nil {
  63. panic("failed to connect database")
  64. }
  65. // Read all enabled feeds
  66. // db.Where("can_sync = ?", 1).Find(&merchantFeeds)
  67. db.Find(&merchant_feeds, 7)
  68. // spew.Dump(merchantFeeds)
  69. for _, feed := range merchant_feeds {
  70. //pull also the column mapping
  71. db.Where("merchant_id = ?", feed.MerchantID).Find(&merchant_csv_mappings)
  72. importProducts(feed.MerchantID, feed.ID, merchant_csv_mappings, db)
  73. }
  74. }
  75. func importProducts(MerchantID int, FeedID int, CsvMapping []MerchantCsvMapping, db *gorm.DB) {
  76. //read csv file
  77. path := strconv.Itoa(MerchantID) + "-" + strconv.Itoa(FeedID) + "-feed.csv"
  78. products := readCsvFile(path)
  79. //a counter to leave out the first line
  80. i := 0
  81. //product is the one we generate and save
  82. var product Product
  83. //p is the product inside the loop
  84. for _, p := range products {
  85. if i == 0 {
  86. i++
  87. continue
  88. }
  89. mapping := CsvMapping[0]
  90. product.MerchantId = MerchantID
  91. idx2, _ := strconv.Atoi(string(mapping.Name))
  92. product.Name = p[idx2]
  93. idx3, _ := strconv.Atoi(string(mapping.ProductNo))
  94. product.ProductNo = p[idx3]
  95. idx4, _ := strconv.Atoi(string(mapping.PriceOld))
  96. product.PriceOld = p[idx4]
  97. idx5, _ := strconv.Atoi(string(mapping.Price))
  98. product.Price = p[idx5]
  99. idx6, _ := strconv.Atoi(string(mapping.Ean))
  100. product.Ean = p[idx6]
  101. idx7, _ := strconv.Atoi(string(mapping.DeepLink))
  102. product.DeepLink = p[idx7]
  103. idx8, _ := strconv.Atoi(string(mapping.ShortDescription))
  104. product.ShortDescription = p[idx8]
  105. idx9, _ := strconv.Atoi(string(mapping.LongDescription))
  106. product.LongDescription = p[idx9]
  107. idx10, _ := strconv.Atoi(string(mapping.MerchantImageURL))
  108. product.MerchantImageUrl = p[idx10]
  109. idx11, _ := strconv.Atoi(string(mapping.AlternateImage))
  110. product.AlternateImage = p[idx11]
  111. idx12, _ := strconv.Atoi(string(mapping.DeliveryTime))
  112. product.DeliveryTime = p[idx12]
  113. idx13, _ := strconv.Atoi(string(mapping.DeliveryCost))
  114. product.DeliveryCost = p[idx13]
  115. //spew.Dump(product)
  116. db.Create(&product)
  117. log.Println(product.ID)
  118. //os.Exit(3)
  119. }
  120. }
  121. func readCsvFile(filePath string) [][]string {
  122. f, err := os.Open(filePath)
  123. if err != nil {
  124. log.Fatal("Unable to read input file "+filePath, err)
  125. }
  126. defer f.Close()
  127. csvReader := csv.NewReader(f)
  128. records, err := csvReader.ReadAll()
  129. if err != nil {
  130. log.Fatal("Unable to parse file as CSV for "+filePath, err)
  131. }
  132. return records
  133. }```
  134. </details>
  135. # 答案1
  136. **得分**: 1
  137. 你的变量的作用域在for循环之外。
  138. 在循环内部,你正在创建产品。
  139. 对于第一个产品,GORM不会向数据库发送ID,数据库将生成下一个可用的ID并返回。GORM将把生成的ID放入`product`中。
  140. 对于第二个产品,GORM将重用该ID,并尝试使用该ID创建另一个产品。数据库将告诉你,该ID已经存在。
  141. 请尝试使用以下代码:
  142. ```go
  143. for _, p := range products {
  144. var product Product
  145. ...
  146. }
英文:

The scope of your variable is outside the for loop.

  1. var product Product
  2. for _, p := range products {
  3. ...
  4. }

Inside the loop, you are creating the product.
For your first product, GORM send no ID to the database, the database will generate the next available ID and return it. GORM will put the generated ID into product.
For your second product, GORM will reuse that ID and try to create another product with that ID. The database will tell you, that ID exists already.

Try this instead:

  1. for _, p := range products {
  2. var product Product
  3. ...
  4. }

huangapple
  • 本文由 发表于 2022年9月9日 12:10:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/73657236.html
匿名

发表评论

匿名网友

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

确定