I am writing on Go and using gorm to deal with Postgres database. I have one instance of Postgres DB, and several instances of my app running simultaneously. It is possible they will unsynchronized in time with each other. It will lead to some problems with my business logic because I need to precisely track changes.
I see a possible solution in using now() instead of the exact time 2022-02-09 17:39:47.785 in database transactions, but I don't know how to do it with gorm. Of course, I can update it later with a separate transaction, or even write a raw SQL query and send it via gorm, but it will add unwanted complexity to my code.
Here is an exampe
package main
import (
"log"
"gorm.io/driver/postgres"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
type Data struct {
gorm.Model
Value string
}
func main() {
// to init test db in docker run
// $docker run --rm -e POSTGRES_HOST_AUTH_METHOD=trust --name pg -p 5432:5432 postgres
db, err := dbClient()
errHandle(err)
err = db.AutoMigrate(&Data{})
errHandle(err)
data := &Data{Value: "some value"}
// add new
err = db.Create(&data).Error
errHandle(err)
data.Value = "some changes"
// update
err = db.Omit("created_at").Save(&data).Error
errHandle(err)
// soft delete
err = db.Delete(&data).Error
errHandle(err)
}
func errHandle(err error) {
if err != nil {
log.Fatal(err)
}
}
func dbClient() (*gorm.DB, error) {
newLogger := logger.Default.LogMode(logger.Info)
c := &gorm.Config{
Logger: newLogger,
}
d := postgres.Open("dbname=postgres host=localhost user=postgres")
return gorm.Open(d, c)
}
If you run it you will see this output
INSERT INTO "data" ("created_at","updated_at","deleted_at","value") VALUES ('2022-02-09 18:22:44.728','2022-02-09 18:22:44.728',NULL,'some value') RETURNING "id";
UPDATE "data" SET "updated_at"='2022-02-09 18:22:44.742',"deleted_at"=NULL,"value"='some changes' WHERE "id" = 1;
UPDATE "data" SET "deleted_at"='2022-02-09 18:22:44.75' WHERE "data"."id" = 1 AND "data"."deleted_at" IS NULL;
I want it to look like that
INSERT INTO "data" ("created_at","updated_at","deleted_at","value") VALUES (now(),now(),NULL,'some value') RETURNING "id";
UPDATE "data" SET "updated_at"=now(),"deleted_at"=NULL,"value"='some changes' WHERE "id" = 1;
UPDATE "data" SET "deleted_at"=now() WHERE "data"."id" = 1 AND "data"."deleted_at" IS NULL;