当前位置: 首页 > 知识库问答 >
问题:

go - Gorm(Postgres)自定义类型主键无法设置自增?

丁德义
2023-05-28

前提:

  1. gorm.io/gorm v1.25.1
  2. gorm.io/driver/postgres v1.5.0

原因,主键在表自动迁移时无法创建自增。

附代码如下,之所以给主键设置为自定义类型,主要是考虑了bigint在前端可能会丢失精度的问题。现在别的都正常,就是自动创建表时,不会设置为自增。

type GVA_MODEL struct {
  ID BigInt `gorm:"primaryKey;autoIncrement:true;type:bigint;size:64;->" form:"id" json:"id" query:"id"` // 主键ID
  // ...
}
// 自定义类型,让客户端以string形式处理BigInt类型的数据
type BigInt json.Number
// Scan 实现 sql.Scanner 接口,Scan 将 value 扫描至 BigInt
func (bigint *BigInt) Scan(value interface{}) error {
  bytes, ok := value.(int64)
  if !ok {
    return errors.New(fmt.Sprint("Failed to unmarshal Int64 value:", value))
  }

  var result = json.Number(strconv.FormatInt(bytes, 10))
  *bigint = BigInt(result)
  return nil
}

// Value 实现 driver.Valuer 接口,Value 返回 BigInt value
func (bigint BigInt) Value() (driver.Value, error) {
  if len(bigint) == 0 {
    return nil, nil
  }
  return json.Number(bigint).Int64()
}

func (BigInt) GormDBDataType(db *gorm.DB, field *schema.Field) string {
  // 根据不同的数据库驱动返回不同的数据类型
  switch db.Dialector.Name() {
  case "mysql", "sqlite":
    return "bigint"
  case "postgres":
    return "bigint"
  }
  return "bigint"
}

共有2个答案

公西志文
2023-05-28

为什么不直接用 int64 ? 要自己写 json.Number ?

唐啸
2023-05-28

通过调试 gorm和driver/postgres的代码,已经搞定了,即在GormDBDataType判断字段是否自增,如果是自增,则返回bigserial

func (bigint BigInt) GormDBDataType(db *gorm.DB, field *schema.Field) string {
    // 根据不同的数据库驱动返回不同的数据类型
    switch db.Dialector.Name() {
    case "mysql", "sqlite":
        return "bigint"
    case "postgres":
        if field.AutoIncrement {
            return "bigserial"
        }
        return "bigint"
    }
    return "bigint"
}

PS:如果字段对应类型实现了GormDBDataType接口,则在表创建时,直接以GormDBDataType返回的类型创建表的字段。

 类似资料:
  • 我试图为我定义的类型生成枚举 从中我了解到可以使用iota创建基于此类型的枚举 是否有方法将具有自定义值的枚举列表自动转换为特定类型。这是我以前使用的,但只将常量的第一个成员转换为自定义类型。 这里有一个类似结果的操场

  • Rust 自定义数据类型主要是通过下面这两个关键字来创建: struct: 定义一个结构体 enum: 定义一个枚举类型 而常量的创建可以通过 const 和 static 关键字来创建。

  • 存在多种方法来重新定义现有类型的行为以及提供新的类型。 重写类型编译 一个常见的需求是强制更改类型的“字符串”版本,即在create table语句或其他SQL函数(如cast)中呈现的版本。例如,应用程序可能希望强制呈现 BINARY 适用于除一个平台外的所有平台 BLOB 待渲染。在本例中,使用现有的泛型类型 LargeBinary ,是大多数用例的首选。但是为了更准确地控制类型,每个方言的编

  • 1. 包含头文件 #import <AdHubSDK/AdHubSDK.h> 2. AdHubCustomView 的创建和初始化 在需要导入广告的ViewController头文件中导入头文件并声明实例以及声明代理 #import <AdHubSDK/AdHubSDK.h> @interface AdHubCustomViewController ()<AdHubCustomViewDele

  • 本文向大家介绍mysql把主键定义为自动增长标识符类型,包括了mysql把主键定义为自动增长标识符类型的使用技巧和注意事项,需要的朋友参考一下 1、把主键定义为自动增长标识符类型 在mysql中,如果把表的主键设为auto_increment类型,数据库就会自动为主键赋值。例如: 一旦把id设为auto_increment类型,mysql数据库会自动按递增的方式为主键赋值。 在MS SQLServ

  • 介绍: 现在基于css font-face的字体图标越来越流行。 这种图标具有矢量图的特点,可以不失真的自由缩放,还可以通过css来设置图标的颜色,还有就是网络上资源特别丰富。X5系统自带了数百个字体图标, 用户还可以通过配置使用自己下载的字体图标, 下边就介绍一下具体的使用方法。 首先以fortawesome 网站为例(网址:http://fortawesome.github.io/Font-A