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

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

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

package main

import (
	"encoding/csv"
	"log"
	"gorm.io/datatypes"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"os"
	"strconv"
)

var merchant_feeds []MerchantFeed
var merchant_csv_mappings []MerchantCsvMapping

type MerchantFeed struct {
	// gorm.Model
	ID         int `gorm:"primary_key"`
	MerchantID int
}

type MerchantCsvMapping struct {
	// gorm.Model
	ID               int `gorm:"primary_key"`
	MerchantId       int
	Name             string
	ProductNo        string
	PriceOld         string
	Ean              string
	Price            string
	Category         int
	DeepLink         string
	ShortDescription string
	LongDescription  string
	BrandMerchant    int
	MerchantImageURL string
	AlternateImage   string
	GalleryImage     int
	GalleryImage2    int
	GalleryImage3    int
	GalleryImage4    int
	DeliveryTime     string
	DeliveryCost     string
}

type Product struct {
	// gorm.Model
	ID                int `gorm:"primary_key"`
	MerchantId        int
	Name              string
	Slug              string
	ProductNo         string
	PriceOld          string
	Tags              datatypes.JSON
	Price             string
	Discount          int
	Ean               string
	DeepLink          string
	ShortDescription  string
	LongDescription   string
	MerchantImageUrl  string
	AlternateImage    string
	DeliveryTime      string
	DeliveryCost      string
}

func main() {
	db, err := gorm.Open(mysql.Open("root@tcp(127.0.0.1:3306)/myshop?parseTime=true"), &gorm.Config{})
	if err != nil {
		panic("failed to connect database")
	}

	db.Find(&merchant_feeds, 7)

	for _, feed := range merchant_feeds {
		db.Where("merchant_id = ?", feed.MerchantID).Find(&merchant_csv_mappings)
		importProducts(feed.MerchantID, feed.ID, merchant_csv_mappings, db)
	}
}

func importProducts(MerchantID int, FeedID int, CsvMapping []MerchantCsvMapping, db *gorm.DB) {
	path := strconv.Itoa(MerchantID) + "-" + strconv.Itoa(FeedID) + "-feed.csv"
	products := readCsvFile(path)

	i := 0
	var product Product

	for _, p := range products {
		if i == 0 {
			i++
			continue
		}

		mapping := CsvMapping[0]

		product.MerchantId = MerchantID
		idx2, _ := strconv.Atoi(string(mapping.Name))
		product.Name = p[idx2]
		idx3, _ := strconv.Atoi(string(mapping.ProductNo))
		product.ProductNo = p[idx3]
		idx4, _ := strconv.Atoi(string(mapping.PriceOld))
		product.PriceOld = p[idx4]
		idx5, _ := strconv.Atoi(string(mapping.Price))
		product.Price = p[idx5]
		idx6, _ := strconv.Atoi(string(mapping.Ean))
		product.Ean = p[idx6]
		idx7, _ := strconv.Atoi(string(mapping.DeepLink))
		product.DeepLink = p[idx7]
		idx8, _ := strconv.Atoi(string(mapping.ShortDescription))
		product.ShortDescription = p[idx8]
		idx9, _ := strconv.Atoi(string(mapping.LongDescription))
		product.LongDescription = p[idx9]
		idx10, _ := strconv.Atoi(string(mapping.MerchantImageURL))
		product.MerchantImageUrl = p[idx10]
		idx11, _ := strconv.Atoi(string(mapping.AlternateImage))
		product.AlternateImage = p[idx11]
		idx12, _ := strconv.Atoi(string(mapping.DeliveryTime))
		product.DeliveryTime = p[idx12]
		idx13, _ := strconv.Atoi(string(mapping.DeliveryCost))
		product.DeliveryCost = p[idx13]

		db.Create(&product)
		log.Println(product.ID)
	}
}

func readCsvFile(filePath string) [][]string {
	f, err := os.Open(filePath)
	if err != nil {
		log.Fatal("Unable to read input file "+filePath, err)
	}
	defer f.Close()

	csvReader := csv.NewReader(f)
	records, err := csvReader.ReadAll()
	if err != nil {
		log.Fatal("Unable to parse file as CSV for "+filePath, err)
	}

	return records
}
英文:

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


import (
"encoding/csv"
"log"
"gorm.io/datatypes"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"os"
"strconv"
)
var merchant_feeds []MerchantFeed
var merchant_csv_mappings []MerchantCsvMapping
type MerchantFeed struct {
// gorm.Model
ID int `gorm:"primary_key"`
MerchantID int 
}
type MerchantCsvMapping struct {
// gorm.Model
ID int `gorm:"primary_key"`
MerchantId       int
Name             string
ProductNo        string
PriceOld         string
Ean              string
Price            string
Category         int
DeepLink         string
ShortDescription string
LongDescription  string
BrandMerchant    int
MerchantImageURL string
AlternateImage   string
GalleryImage     int
GalleryImage2    int
GalleryImage3    int
GalleryImage4    int
DeliveryTime     string
DeliveryCost     string
}
type Product struct {
// gorm.Model
ID int `gorm:"primary_key"`
MerchantId       int
Name             string
Slug             string
ProductNo        string
PriceOld         string
Tags             datatypes.JSON
Price            string
Discount         int
Ean              string
DeepLink         string
ShortDescription string
LongDescription  string
MerchantImageUrl    string
AlternateImage   string
DeliveryTime     string
DeliveryCost     string
}
func main() {
db, err := gorm.Open(mysql.Open("root@tcp(127.0.0.1:3306)/myshop?parseTime=true"), &gorm.Config{})
if err != nil {
panic("failed to connect database")
}
// Read all enabled feeds
//   db.Where("can_sync = ?", 1).Find(&merchantFeeds)
db.Find(&merchant_feeds, 7)
//   spew.Dump(merchantFeeds)
for _, feed := range merchant_feeds {
//pull also the column mapping
db.Where("merchant_id = ?", feed.MerchantID).Find(&merchant_csv_mappings)
importProducts(feed.MerchantID, feed.ID, merchant_csv_mappings, db)
}
}
func importProducts(MerchantID int, FeedID int, CsvMapping []MerchantCsvMapping,  db *gorm.DB) {
//read csv file
path := strconv.Itoa(MerchantID) + "-" + strconv.Itoa(FeedID) + "-feed.csv"
products := readCsvFile(path)
//a counter to leave out the first line
i := 0
//product is the one we generate and save
var product Product
//p is the product inside the loop
for _, p := range products {
if i == 0 {
i++
continue
}
mapping := CsvMapping[0]
product.MerchantId = MerchantID
idx2, _ := strconv.Atoi(string(mapping.Name))
product.Name = p[idx2]
idx3, _ := strconv.Atoi(string(mapping.ProductNo))
product.ProductNo = p[idx3]
idx4, _ := strconv.Atoi(string(mapping.PriceOld))
product.PriceOld = p[idx4]
idx5, _ := strconv.Atoi(string(mapping.Price))
product.Price = p[idx5]
idx6, _ := strconv.Atoi(string(mapping.Ean))
product.Ean = p[idx6]
idx7, _ := strconv.Atoi(string(mapping.DeepLink))
product.DeepLink = p[idx7]
idx8, _ := strconv.Atoi(string(mapping.ShortDescription))
product.ShortDescription = p[idx8]
idx9, _ := strconv.Atoi(string(mapping.LongDescription))
product.LongDescription = p[idx9]
idx10, _ := strconv.Atoi(string(mapping.MerchantImageURL))
product.MerchantImageUrl = p[idx10]
idx11, _ := strconv.Atoi(string(mapping.AlternateImage))
product.AlternateImage = p[idx11]
idx12, _ := strconv.Atoi(string(mapping.DeliveryTime))
product.DeliveryTime = p[idx12]
idx13, _ := strconv.Atoi(string(mapping.DeliveryCost))
product.DeliveryCost = p[idx13]
//spew.Dump(product)
db.Create(&product)
log.Println(product.ID)
//os.Exit(3)
}
}
func readCsvFile(filePath string) [][]string {
f, err := os.Open(filePath)
if err != nil {
log.Fatal("Unable to read input file "+filePath, err)
}
defer f.Close()
csvReader := csv.NewReader(f)
records, err := csvReader.ReadAll()
if err != nil {
log.Fatal("Unable to parse file as CSV for "+filePath, err)
}
return records
}```
</details>
# 答案1
**得分**: 1
你的变量的作用域在for循环之外。
在循环内部,你正在创建产品。
对于第一个产品,GORM不会向数据库发送ID,数据库将生成下一个可用的ID并返回。GORM将把生成的ID放入`product`中。
对于第二个产品,GORM将重用该ID,并尝试使用该ID创建另一个产品。数据库将告诉你,该ID已经存在。
请尝试使用以下代码:
```go
for _, p := range products {
var product Product
...
}
英文:

The scope of your variable is outside the for loop.

var product Product

for _, p := range products {
  ...
}

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:

for _, p := range products {
  var product Product

  ...
}

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:

确定