According to GORM's docs:
Updates supports update with struct or map[string]interface{}, when updating with struct it will only update non-zero fields by default
I have an entry in my database already for the Service
with ID, abc123
. I am attempting to take an object that looks like the one below:
Service{
ID: "abc123",
Name: "new service name",
CreatedAt: nil,
}
And use it to update the my existing record. But when I call:
tx.Model(&service).Updates(service)
the CreatedAt
value in the database is overwritten with nil
. How can I update my database record without overwritting the CreatedAt
value?
Update: Below is my Service
struct
type Service struct {
ID string `gorm:"not null;type:char(32);primary_key;column:id"`
Name string `json:"name" gorm:"size:50;not null;"`
CreatedAt *time.Time
UpdatedAt time.Time
DeletedAt *time.Time `gorm:"index"`
}
I've tried two different variations for my Service
struct. the other is with CreatedAt
being of type time.Time
instead of *time.Time
. With *time.Time
it will overwrite the value in my DB with a null value. With time.Time
it attempts to overwrite the value in the DB with an uninitialized time value and throws the error: Error 1292: Incorrect datetime value: '0000-00-00' for column 'created_at' at row 1
A zero value, or a default value, for a time.Time
field type inside a struct is time.Time{}
. When using Updates
, either don't populate the CreatedAt
field, or assign time.Time{}
value to it.
In the example below, the default or zero value is printed out for CreatedAt
field in both cases.
package main
import (
"fmt"
"time"
)
type T struct {
CreatedAt time.Time
C int
S string
}
func main() {
fmt.Println(T{C: 1, S: "one"})
fmt.Println(T{C: 2, S: "two", CreatedAt: time.Time{}})
}
// {0001-01-01 00:00:00 +0000 UTC 1 one}
// {0001-01-01 00:00:00 +0000 UTC 2 two}
EDIT:
Also, I'm not sure how even CreatedAt: nil,
compiles if the CreatedAt
field is of time.Time
type, and not *time.Time
.
Since you've updated the Service
struct and CreatedAt
field type to *time.Time
, following should work:
tx.Model(&service).Updates(Service{Name: service.Name}) // add all fields that you want to be updated.
// resulting query
// UPDATE services SET name = 'new service name' WHERE id = 'abc123';
An official GORM example is here
Additionally, you can omit the created_at
field like this:
tx.Model(&service).Omit("created_at").Updates(service)