Your Question

I'm trying to write a generic function to bulk upsert objects in MSSQL and I wanted to check if this looks correct? I've used some code from this stackoverflow question, but the docs are a little sparse regarding the clause.OnConflict for my current knowledge.

func BatchUpsertObjectsToDatabase[T any](db *gorm.DB, objects []T) {
    db.AutoMigrate(objects[0])

    s, err := schema.Parse(objects[0], &sync.Map{}, schema.NamingStrategy{})
    if err != nil {
        log.Fatal("failed to parse schema for object")
    }
    var primaryKeys []clause.Column
    updateFields := []string{}
    for _, f := range s.Fields {
        if !f.PrimaryKey {
            updateFields = append(updateFields, f.DBName)
        }
        if f.PrimaryKey {
            c := clause.Column{
                Name: f.DBName,
            }
            primaryKeys = append(primaryKeys, c)
        }
    }
    db.Clauses(clause.OnConflict{
        Columns:   primaryKeys,
        DoUpdates: clause.AssignmentColumns(updateFields),
    }).CreateInBatches(objects, 100)
}

Am I right in assuming that in clause.OnConflict the Columns field is to specify the primary key since this is what the conflict would be caused by? And that DoUpdates specifies which fields should still be updated?

So, in my case here I'm saying conflict on all primary keys and update all columns on conflict?

The document you expected this should be explained

https://gorm.io/docs/create.html#Batch-Insert

Expected answer

I'd like for this to be correct and possibly pointing to some documentation I've missed, or for the documentation to be updated slightly?

Many thanks.