Flask SQLAlchemy 浮点数类型Float 丢失精度 解决方法
HDUZN

数据库里,用到float类型的时候,会有精度损失。

比如,用Flask的SQLAlchemy的时候,定义数据库表对应的字段的时候,如果MySQL里存的是float类型,那就定义成 SQLAlchemy的Float 类型。
然后,当我把一个2位小数的数存进数据库,一查看,有的变成了1位小数,有的直接无小数了,反正就奇奇怪怪的。这就是因为精度损失了。

我们一般在操作数据库的时候,可能用 decimal 或者 double 这样的字段类型来替换 float 类型,就可以解决这个问题了。

但是 SQLAlchemy 里并没有直接的 double 或者 decimal 类型。
然后就找到了对应的 Numeric 类型,是对应 Python中的Decimal 类型的。

解决方法过程

如果不想看解决的过程的,建议直接跳到看第3点【总结】部分就行。

1、把字段的定义由原来的:

1
high = db.Column(db.Float)

改成:

1
high = db.Column(db.Numeric)

去数据库里一看表设计,这个high字段类型已经成功变成了 decimal 类型。

但是,发现直接没有小数了,直接就变成整数了。
一看表设计,虽然 high 字段已经变成了 decimal 类型,长度为10,但小数点位数却是空的,那就相当于0,没有小数。

2、设定小数点位数

然后,查看了SQLAlchemy文档, Numeric 定义的部分。主要看一下参数有些啥。

1
class sqlalchemy.types.NUMERIC(precision=None, scale=None, decimal_return_scale=None, asdecimal=True)

第1个参数 precision:长度
第2个参数 scale:小数点位数

因为我看到长度默认就是10了,于是,就傻傻觉得只设一下scale参数就行。就改成了:

1
high = db.Column(db.Numeric(scale=2))

结果,还是不行,压根没效果。
然后,一看,一想,才觉得,索性要把前面的precision 参数也设一下。就改成了:

1
high = db.Column(db.Numeric(10,2))

成功了!!!

3、总结

原来定义是 Float 类型的字段是这样定义的:

1
high = db.Column(db.Float)

然后改成 Numeric 类型(对应数据库中 decimal 类型)是这样的(保留2位小数):

1
high = db.Column(db.Numeric(10,2))

SQLAlchemy 常用的字段类型

类型名 python中类型 说明
Integer int 普通整数,一般是32位
SmallInteger int 取值范围小的整数,—般是16位
BigInteger int或long 不限制精度的整数
Float float 浮点数
Numeric decimal.Decimal 固定精度数字的类型,例如 NUMERIC 或 DECIMAL
String str 变长字符串
Text str 变长字符串,对较长或不限长度的字符串做了优化
Boolean bool 布尔值
Date datetime.date 时间
Time datetime.datetime 日期和时间
LargeBinary str 二进制文件
  • 本文标题:Flask SQLAlchemy 浮点数类型Float 丢失精度 解决方法
  • 本文作者:HDUZN
  • 创建时间:2022-04-10 19:05:00
  • 本文链接:http://hduzn.cn/2022/04/10/Flask-SQLAlchemy浮点数类型Float丢失精度解决方法/
  • 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
 评论