GORM Playground Link
https://github.com/go-gorm/playground/pull/559
Description
SQLite supports multiple OnConflict clauses with different conflict targets. But current Gorm's API doesn't seem to support that: if I call AddClause several times with different OnConflict values, the latter one just overwrites the former one, because clauses are stored in a map under their names.
I had to workaround it by "subclassing" the OnConflict struct and changing the subclass name to ON CONFLICT (with extra whitespace), so that it is properly recognized by SQLite but Gorm considers it a different clause type:
import "gorm.io/gorm/callbacks"
import "gorm.io/gorm/clause"
...
callbacks.RegisterDefaultCallbacks(db, &callbacks.Config{
CreateClauses: []string{
"INSERT",
"VALUES",
"ON CONFLICT ", // my injected OnConflict2 struct
"ON CONFLICT", // the original OnConflict
"RETURNING", // without adding it here it wasn't added to auto-generated queries for some reason
},
})
...
type OnConflict2 struct{
clause.OnConflict
}
func (oc OnConflict2) Name() string {
return "ON CONFLICT "
}
...
func (m *MyModel) BeforeCreate(tx *gorm.DB) error {
tx.Statement.AddClause(OnConflict2{clause.OnConflict{
Columns: []clause.Column{{Name: "my_unique_column"}},
DoUpdates: clause.AssignmentColumns([]string{
"updated_at",
}),
}})
tx.Statemenet.AddClause(OnConflict{
Columns: []clause.Column{{Name: "id"}},
UpdateAll: true, // UpdateAll doesn't seem to work properly for OnConflict2
})
return nil
}
Comment From: github-actions[bot]
The issue has been automatically marked as stale as it missing playground pull request link, which is important to help others understand your issue effectively and make sure the issue hasn't been fixed on latest master, checkout https://github.com/go-gorm/playground for details. it will be closed in 30 days if no further activity occurs. if you are asking question, please use the Question template, most likely your question already answered https://github.com/go-gorm/gorm/issues or described in the document https://gorm.io ✨ Search Before Asking ✨
Comment From: MarSoft
Added the playground link: https://github.com/go-gorm/playground/pull/559
Comment From: MarSoft
I understand that fixing this issue would likely require major rework of Gorm's internal architecture. But at least it should be properly documented, and I think some workarounds could be documented too.
Maybe the one I used. Or maybe make clause.OnConflict struct support several targets somehow?..