如何在GORM与SQLite3中使用pgtype.Numeric?遇扫描错误求解决
问题根源
你用错了类型适配——pgtype.Numeric是PostgreSQL专属的类型实现,专门用来映射PostgreSQL的numeric/decimal字段,但你连接的是SQLite数据库。SQLite没有原生的高精度数值类型,存储时会把你的数值转成int64,查询返回的也是int64,自然没法扫描到pgtype.Numeric结构体里,这就是报错的原因。
方案一:继续用SQLite存储超大高精度数值
SQLite本身没有专门的高精度数值类型,推荐用字符串类型存储,既能完整保留精度,又能避免类型不兼容问题:
- 修改模型定义:
type Model struct { gorm.Model Foo string `gorm:"type:text;not null"` // 用text类型确保能存超长字符串 }
- 读写时手动转换为
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,步骤如下:
- 安装依赖:
go get gorm.io/driver/postgres go get github.com/jackc/pgtype
- 修改代码适配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
相关产品推荐
相关产品推荐

