GORM Playground Link
https://github.com/go-gorm/playground/pull/598
Description
See playground for example - with sqlite, if you set a string field to be gorm:"default:null", and its value is empty string, when you go to insert multiple entities, gorm tries to use the DEFAULT keyword (I believe it's from here), which is invalid in sqlite, causing an error. Is there any way to fix this aside from inserting each entity one at a time?
Comment From: black-06
It's related to https://github.com/go-gorm/sqlite/blob/0d652e16cdf4ab215f20d973cb89c70729e18a84/sqlite.go#L124-131
func (dialector Dialector) DefaultValueOf(field *schema.Field) clause.Expression {
if field.AutoIncrement {
return clause.Expr{SQL: "NULL"}
}
// doesn't work, will raise error
return clause.Expr{SQL: "DEFAULT"}
}
Is this a bug ? @a631807682
Comment From: a631807682
It's related to https://github.com/go-gorm/sqlite/blob/0d652e16cdf4ab215f20d973cb89c70729e18a84/sqlite.go#L124-131
```go func (dialector Dialector) DefaultValueOf(field *schema.Field) clause.Expression { if field.AutoIncrement { return clause.Expr{SQL: "NULL"} }
// doesn't work, will raise error return clause.Expr{SQL: "DEFAULT"} } ```
Is this a bug ? @a631807682
I didn't investigate, but it should be a bug
Comment From: black-06
Sry, I was wrong, this is not a bug. There is no way to insert both the specified value and the default value in SQLite.
Maybe you can assign the default value to the field in the hook, e.g.
type NullableStringType struct {
Value string `gorm:"default:'abcd'"`
}
func (p *NullableStringType) BeforeCreate(tx *gorm.DB) (err error) {
if p.Value == "" {
p.Value = 'abcd'
}
}
Comment From: a631807682
Perhaps we should clearly point out that sqlite does not support it, and the meaning of the comments here is not clear enough.
Anyway, sqlite doesn't support that, we currently don't have label management for won't fix, so I close it.
Comment From: samc1213
Thank you both for taking a look.
For anyone looking at this issue in the future:
The simplest workaround is to use individual insert statements. I.e., instead of
value := NullableStringType{Value: "jinzhu"}
value2 := NullableStringType{}
values := []NullableStringType{value, value2}
tx := DB.Create(&values)
do this:
value := NullableStringType{Value: "jinzhu"}
value2 := NullableStringType{}
tx := DB.Create(&value)
tx = DB.Create(&value2)
I agree that this is hard to fix given SQLite's lack of support for DEFAULT keyword.
Comment From: dismantl
Perhaps we should clearly point out that sqlite does not support it, and the meaning of the comments here is not clear enough.
It would be great if this were somewhere in the documentation, as I've spend hours today trying to track down this bug.
Comment From: bkmeneguello
Is it possible to disable batch if the database doesn't support it? Maybe during the Create function call check if the schema have default values and if the database supports and "automagically" consider the batch size as "1"?
Comment From: Baldur404
Is it possible to disable batch if the database doesn't support it? Maybe during the Create function call check if the schema have default values and if the database supports and "automagically" consider the batch size as "1"?
yes ,it’s counter-intuitive,if a developer does not check doc or this issue,they will write unpredictable code,In my opinion fixing it to support batch insertion of default values is not difficult,the key point is whether to implement it or not. Grom is a framework,the framework should encapsulation code to give developer a clear and easy way to use it -personal opinion