You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在GORM与SQLite3中使用pgtype.Numeric?遇扫描错误求解决

问题根源

你用错了类型适配——pgtype.Numeric是PostgreSQL专属的类型实现,专门用来映射PostgreSQL的numeric/decimal字段,但你连接的是SQLite数据库。SQLite没有原生的高精度数值类型,存储时会把你的数值转成int64,查询返回的也是int64,自然没法扫描到pgtype.Numeric结构体里,这就是报错的原因。


方案一:继续用SQLite存储超大高精度数值

SQLite本身没有专门的高精度数值类型,推荐用字符串类型存储,既能完整保留精度,又能避免类型不兼容问题:

  1. 修改模型定义:
type Model struct {
    gorm.Model
    Foo string `gorm:"type:text;not null"` // 用text类型确保能存超长字符串
}
  1. 读写时手动转换为big.Int/big.Float:
package main

import (
  "gorm.io/driver/sqlite"
  "gorm.io/gorm"
  "math/big"
)

type Model struct {
  gorm.Model
  Foo string `gorm:"type:text;not null"`
}

func main() {
  db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
  if err != nil {
    panic("failed to connect database")
  }
  db.AutoMigrate(&Model{})

  // 存储:把big.Int转成字符串
  num := big.NewInt(10000000)
  db.Create(&Model{Foo: num.String()})

  // 查询:把字符串转回big.Int
  var m Model
  db.First(&m)
  result := new(big.Int)
  result.SetString(m.Foo, 10)
  // 现在result就是你要的高精度数值
}

方案二:切换到PostgreSQL(推荐,原生支持高精度数值)

如果可以换成PostgreSQL,就能完美使用pgtype.Numeric,步骤如下:

  1. 安装依赖:
go get gorm.io/driver/postgres
go get github.com/jackc/pgtype
  1. 修改代码适配PostgreSQL:
    注意初始化pgtype.Numeric时要设置Scale(小数位数,这里设为0表示整数),否则可能存储或读取异常:
package main

import (
  "gorm.io/driver/postgres"
  "gorm.io/gorm"
  "math/big"

  "github.com/jackc/pgtype"
)

type Model struct {
  gorm.Model
  Foo pgtype.Numeric `gorm:"type:numeric;not null"` // 明确指定字段类型为numeric
}

func main() {
  // 替换成你的PostgreSQL连接信息
  dsn := "host=localhost user=postgres password=yourpassword dbname=test port=5432 sslmode=disable TimeZone=Asia/Shanghai"
  db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
  if err != nil {
    panic("failed to connect database")
  }
  db.AutoMigrate(&Model{})

  // 正确初始化pgtype.Numeric:设置Int、Scale、Status
  var num pgtype.Numeric
  num.Int = big.NewInt(10000000)
  num.Scale = 0 // 小数位数,根据你的需求调整
  num.Status = pgtype.Present
  db.Create(&Model{Foo: num})

  // 查询读取正常
  var m Model
  db.First(&m)
  // 使用m.Foo.Int获取big.Int数值
}

内容的提问来源于stack exchange,提问作者BigP

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 00:10:42