英文:
How do you do UUID in Golangs Gorm?
问题
我有以下模型...
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
}
我尝试了几种不同的方法,但是这种方式会抛出"(pq: relation "users" does not exist)"的错误。我没有相关的模型,只有这一个模型。
我尝试使用...
func (user *User) BeforeCreate(scope *gorm.Scope) error {
scope.SetColumn("ID", uuid.NewV4())
return nil
}
还使用了一个uuid库,但是也没有成功。
英文:
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.
答案1
得分: 14
对于postgresql
,我做了以下操作:
- 使用
go get github.com/google/uuid
命令安装了github.com/google/uuid
库。 - 使用
uuid.UUID
作为类型(来自"github.com/google/uuid"),例如:ID uuid.UUID `gorm:"type:uuid;default:uuid_generate_v4()"`
- 为Postgres数据库添加了uuid-ossp扩展,例如:
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
- 当调用DB的Create()方法时,uuid会自动生成。
更新:pg14+ gen_random_uuid()
(正如Doron Segal
的评论中提到的)
pg 14内置了函数gen_random_uuid()
来生成uuid v4,例如:
创建表:
create table uuid_test (uid text default gen_random_uuid());
插入一行:
insert into uuid_test(uid) values (DEFAULT);
然后uid
列会自动生成。
类似地,在go中,你可以将该函数作为默认值使用,例如:
ID uuid.UUID `gorm:"type:uuid;default:gen_random_uuid()"`
顺便说一下,gen_random_uuid()
函数目前仅支持uuid v4,如果要使用其他版本,仍然需要uuid-ossp
扩展。
英文:
For postgresql
, here is what I did:
go get github.com/google/uuid
- Use
uuid.UUID
(from "github.com/google/uuid"), as type,
e.g
<pre>ID uuid.UUIDgorm:"type:uuid;default:uuid_generate_v4()"
</pre> - Add uuid-ossp extension for postgres database,
e.g
<pre>CREATE EXTENSION IF NOT EXISTS "uuid-ossp";</pre> - Then, when you call DB's Create() method, the uuid is generated automatically.
Update: pg14+ gen_random_uuid()
(as mentioned in Doron Segal
's comment)
pg 14 has built-in function gen_random_uuid()
to generate uuid v4, e.g:
create table:
> create table uuid_test (uid text default gen_random_uuid());
insert a row:
> insert into uuid_test(uid) values (DEFAULT);
Then uid
column is generated automatically.
Similiar, in go you can use the function as defaul value I think, e.g:
> ID uuid.UUID gorm:"type:uuid;default:gen_random_uuid()"
BTW, the gen_random_uuid()
function only support uuid v4 now, to use other versions, you still need uuid-ossp
extension.
答案2
得分: 13
原来我试图将UUID存储为错误的类型,我原来的写法是...
func (user *User) BeforeCreate(scope *gorm.Scope) error {
scope.SetColumn("ID", uuid.NewV4())
return nil
}
但实际上应该是...
func (user *User) BeforeCreate(scope *gorm.Scope) error {
scope.SetColumn("ID", uuid.NewV4().String())
return nil
}
英文:
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
}
答案3
得分: 7
这是我对 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"`
}
// 注意:如果函数签名不包括 `*gorm.DB` 和 `error`,Gorm 将会失败
func (user *User) BeforeCreate(tx *gorm.DB) (err error) {
// UUID 版本 4
user.Id = uuid.NewString()
return
}
注意事项:
-
对于 Google UUID 包,
uuid.New()
和uuid.NewString()
方法使用的是 UUID 版本 4。虽然在文档(http://pkg.go.dev/github.com/google/uuid)中没有明确说明,但通过查看源代码,可以看到这些方法是对uuid.NewRandom()
的封装,而uuid.NewRandom()
被声明为 UUID 版本 4。 -
虽然有些人推荐使用 Satori UUID 包(https://github.com/satori/go.uuid),但基准测试显示它的性能比 Google UUID 包低 3.3 倍(https://gist.github.com/mattes/69a4ab7027b9e8ee952b5843e7ca6955)。
英文:
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)
答案4
得分: 5
go get github.com/jinzhu/gorm
go get github.com/satori/go.uuid
尝试创建自己的模型基础模型,以替代gorm.Model
,如下所示:
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"`
}
然后,您可以使用在创建任何记录之前调用的方法来填充此字段,如下所示:
func (base *Base) BeforeCreate(scope *gorm.Scope) error {
id, err := uuid.NewV4()
if err != nil {
return err
}
return scope.SetColumn("ID", uuid.String())
}
因此,对于您的特定情况,您将拥有:
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"`
}
有关更多详细信息,请参阅此处。
英文:
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
答案5
得分: 1
错误 (pq: relation "users" does not exist)
通常意味着数据库中不存在表 users
。这与两个模型之间的关系无关。
所以基本上,你首先需要在数据库中创建该表(或按照 @Apin 的建议自动迁移数据库)。然后尝试重新运行相同的代码。
英文:
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.
答案6
得分: 0
以下是翻译好的内容:
这些方法在我使用 gorm v1.21 时都没有起作用。
以下是我的解决方案。请注意,我使用了 satori/go.uuid 库来生成 UUID,但是使用 google 的库的代码几乎相同。
type UUIDBaseModel struct {
ID uuid.UUID `gorm:"primary_key" json:"id"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt *time.Time `sql:"index" json:"deleted_at"`
}
func (base *UUIDBaseModel) BeforeCreate(tx *gorm.DB) error {
uuid := uuid.NewV4().String()
tx.Statement.SetColumn("ID", uuid)
return nil
}
英文:
None of these worked for me using gorm v1.21.
Here was my solution. Note that I'm using the satori/go.uuid library for generating UUID, but code with google's library is near identical.
type UUIDBaseModel struct {
ID uuid.UUID `gorm:"primary_key" json:"id"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt *time.Time `sql:"index" json:"deleted_at"`
}
func (base *UUIDBaseModel) BeforeCreate(tx *gorm.DB) error {
uuid := uuid.NewV4().String()
tx.Statement.SetColumn("ID", uuid)
return nil
}
答案7
得分: 0
现在我使用的是 Gorm 2.0,这个方法有效:
go get github.com/satori/go.uuid
type Tablename struct {
ID string `sql:"type:uuid;primary_key;default:uuid_generate_v4()"`
}
英文:
Now I used Gorm 2.0 and this worked:
go get github.com/satori/go.uuid
type Tablename struct {
ID string `sql:"type:uuid;primary_key;default:uuid_generate_v4()"`
}
答案8
得分: 0
使用MySQL 8.0和gorm(gorm.io/driver/mysql v1.5.0和gorm.io/gorm v1.25.1):
type ModelUUID struct {
ID string `gorm:"type:binary(16);column:id;primaryKey;default:(UUID_TO_BIN(UUID(), 1));" json:"id" validate:"required"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"-"`
DeletedAt gorm.DeletedAt `json:"-" gorm:"index" swaggerignore:"true"`
}
英文:
With MySQL 8.0 and gorm (gorm.io/driver/mysql v1.5.0 and gorm.io/gorm v1.25.1):
type ModelUUID struct {
ID string `gorm:"type:binary(16);column:id;primaryKey;default:(UUID_TO_BIN(UUID(), 1));" json:"id" validate:"required"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"-"`
DeletedAt gorm.DeletedAt `json:"-" gorm:"index" swaggerignore:"true"`
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论