Home > Blockchain >  AutIncrement doesnt work for me with GORM
AutIncrement doesnt work for me with GORM

Time:09-12

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

  ...
}
  • Related