Flask SQLAlchemy 浮点数类型Float 丢失精度 解决方法
数据库里,用到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 许可协议。转载请注明出处!
评论