【问题标题】:How do you do UUID in Golangs Gorm?你如何在 Golang Gorm 中做 UUID?
【发布时间】:2016-07-28 22:40:14
【问题描述】:

我有以下型号...

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 库,但也没有运气。

【问题讨论】:

  • 看来您的用户表在数据库中不存在。你自动迁移了吗?
  • 目前有没有更好的方法?

标签: postgresql go go-gorm


【解决方案1】:

原来我试图将 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
}

【讨论】:

  • 您应该使用return scope.SetColumn("ID", uuid.NewV4().String()) 而不是忽略SetColumn 的结果
【解决方案2】:

为此,您需要 gormgo.uuid

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"`
}

更多详情请见here

【讨论】:

  • default:uuid_generate_v4() 不会自动为我们生成 UUID 吗?
  • 这肯定会返回错误uuid, err := uuid.NewV4().String()
  • 把.String()放到这一行return scope.SetColumn("ID", uuid.String())
  • 这在撰写本文时有效。我没有跟进,也没有以我目前的身份积极使用 Go,但我会做出要求的更改。
【解决方案3】:

这是我对 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
}

注意事项:

  1. 对于 Google UUID 包,uuid.New()uuid.NewString() 方法使用 UUID 版本 4。这在文档中没有明确说明(http://pkg.go.dev/github.com/google/uuid),但是通过查看源代码,您可以看到这些是 uuid.NewRandom() 的包装器,它被称为 UUID 版本 4。

  2. 虽然有些人推荐 Satori UUID 包 (https://github.com/satori/go.uuid),但基准测试表明它的性能比 Google UUID 包低 3.3 倍 (https://gist.github.com/mattes/69a4ab7027b9e8ee952b5843e7ca6955)

【讨论】:

  • 应该是uuid.New() 有效。请更新您的答案。
  • @HalfWebDev 据我了解,uuid.New() 返回一个 16 字节数组,而不是字符串。如果您对为什么使用uuid.New() 优于uuid.NewString() 有一个令人信服的论据,那么我很乐意更新示例代码。在我看来,uuid.NewString() 更好,因为字符串是可读的,并且在不同的数据库中得到很好的支持。
  • 嗯,好的。从我尝试过的NewString() 根本不是uuid 上的方法
  • @HalfWebDev NewString 在 v1.2.0 (pkg.go.dev/github.com/google/uuid#NewString) 中添加。用go get -u github.com/google/uuid更新包是否包含方法?
  • 对,我以为我有最新的包,因为我刚刚开始工作。事实证明,我在1.0.0。将检查最新版本
【解决方案4】:

对于postgresql,这是我所做的:

  • go get github.com/google/uuid
  • 使用uuid.UUID(来自“github.com/google/uuid”)作为类型,
    例如
    ID uuid.UUID `gorm:"type:uuid;default:uuid_generate_v4()"`
  • 为 postgres 数据库添加 uuid-ossp 扩展,
    例如
    如果“uuid-ossp”不存在则创建扩展;
  • 然后,当您调用 DB 的 Create() 方法时,会自动生成 uuid。

【讨论】:

    【解决方案5】:

    错误(pq: relation "users" does not exist) 通常表示, users 在数据库中不存在。它与两个模型之间的关系无关。

    所以基本上,您首先需要在数据库中创建表(或者按照@Apin 的建议自动迁移数据库)。并尝试重新运行相同的代码。

    【讨论】:

      【解决方案6】:

      这些都不适用于我使用 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
      }
      

      【讨论】:

        猜你喜欢
        • 2020-07-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-06-20
        • 2017-05-12
        • 1970-01-01
        • 1970-01-01
        • 2015-06-08
        相关资源
        最近更新 更多