Gorm(Postgres)自定义类型主键无法设置自增?
前提:
- gorm.io/gorm v1.25.1
- 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":
if field.AutoIncrement { // 这是已修复后的
return "bigserial"
}
return "bigint"
}
return "bigint"
}
回复
1个回答
test
2024-07-03
通过调试 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返回的类型创建表的字段。
回复
适合作为回答的
- 经过验证的有效解决办法
- 自己的经验指引,对解决问题有帮助
- 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
- 询问内容细节或回复楼层
- 与题目无关的内容
- “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容