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
}```
CodePudding user response:
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
...
}