How do you do UUID in Golangs Gorm?
Solution 1
Turns out I was trying to store the UUID as the wrong type, I was doing...
func (user *User) BeforeCreate(scope *gorm.Scope) error {
scope.SetColumn("ID", uuid.NewV4())
return nil
}
When it needed to be...
func (user *User) BeforeCreate(scope *gorm.Scope) error {
scope.SetColumn("ID", uuid.NewV4().String())
return nil
}
Solution 2
For this you will need gorm and go.uuid
go get github.com/jinzhu/gorm
go get github.com/satori/go.uuid
Try creating your own model base model in place of gorm.Model
like so:
type Base struct {
ID string `sql:"type:uuid;primary_key;default:uuid_generate_v4()"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt *time.Time `sql:"index" json:"deleted_at"`
}
You would then populate this field using a method called before creation of any record, like so:
func (base *Base) BeforeCreate(scope *gorm.Scope) error {
id, err := uuid.NewV4()
if err != nil {
return err
}
return scope.SetColumn("ID", uuid.String())
}
Therefore, for your particular case, you would have:
type User struct {
Base
FirstName string `form:"first_name" json:"first_name,omitempty"`
LastName string `form:"last_name" json:"last_name,omitempty"`
Password string `form:"password" json:"password" bindind:"required"`
Email string `gorm:"type:varchar(110);unique_index" form:"email" json:"email,omitempty" binding:"required"`
Location string `form:"location" json:"location,omitempty"`
Avatar string `form:"avatar" json:"avatar,omitempty"`
BgImg string `form:"bg_img" json:"bg_img,omitempty"`
}
More details on this can be found here
Solution 3
This was my solution for Gorm v1.21
go get gorm.io/gorm
go get gorm.io/driver/postgres
go get github.com/google/uuid
import (
"gorm.io/gorm"
"github.com/google/uuid"
)
type User struct {
Id: string `gorm:"primaryKey"`
}
// Note: Gorm will fail if the function signature
// does not include `*gorm.DB` and `error`
func (user *User) BeforeCreate(tx *gorm.DB) (err error) {
// UUID version 4
user.Id = uuid.NewString()
return
}
Notes:
-
For the Google UUID package, the methods
uuid.New()
anduuid.NewString()
use UUID version 4. This is not clearly stated in the documentation (http://pkg.go.dev/github.com/google/uuid), but by looking into the source code, you can see that these are wrappers arounduuid.NewRandom()
which is stated as being UUID version 4. -
While some recommend the Satori UUID package (https://github.com/satori/go.uuid), benchmarks show that it has 3.3x lower performance than the Google UUID package (https://gist.github.com/mattes/69a4ab7027b9e8ee952b5843e7ca6955)
Solution 4
For postgresql
, here is what I did:
go get github.com/google/uuid
- Use
uuid.UUID
(from "github.com/google/uuid"), as type,
e.gID uuid.UUID `gorm:"type:uuid;default:uuid_generate_v4()"`
- Add uuid-ossp extension for postgres database,
e.gCREATE EXTENSION IF NOT EXISTS "uuid-ossp";
- Then, when you call DB's Create() method, the uuid is generated automatically.
Solution 5
The error (pq: relation "users" does not exist)
usually means that, the table users
does not exists in the database. It has nothing to do with the relationship between two models.
So basically, You first need to create the table in the database (Or auto migrate the database As per @Apin suggest). And try to re-run the same code.
Ewan Valentine
Updated on October 12, 2021Comments
-
Ewan Valentine over 2 years
I have the following model...
type User struct { ID string `sql:"type:uuid;primary_key;default:uuid_generate_v4()"` FirstName string `form:"first_name" json:"first_name,omitempty"` LastName string `form:"last_name" json:"last_name,omitempty"` Password string `form:"password" json:"password" bindind:"required"` Email string `gorm:"type:varchar(110);unique_index" form:"email" json:"email,omitempty" binding:"required"` Location string `form:"location" json:"location,omitempty"` Avatar string `form:"avatar" json:"avatar,omitempty"` BgImg string `form:"bg_img" json:"bg_img,omitempty"` CreatedAt time.Time UpdatedAt time.Time DeletedAt time.Time }
I've tried several different ways, but this way throws
(pq: relation "users" does not exist)
. I have no related models, it's literally just that one model.I've tried using...
func (user *User) BeforeCreate(scope *gorm.Scope) error { scope.SetColumn("ID", uuid.NewV4()) return nil }
Along with a uuid lib, but had no luck with that either.