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

如何使用Python SQLAlchemy与SQLite存储指定精度的浮点数

问题原因

你遇到的Float的precision参数不生效的问题,本质是两个层面的限制:

  • SQLite本身是动态类型系统,属于类型亲和的设计,即便你手动写DDL指定FLOAT(3),SQLite也不会真的限制存储的浮点精度,底层还是存储为8字节双精度浮点数(REAL类型)
  • SQLAlchemy的SQLite方言实现中,默认会忽略Float类型的precision参数,所以不会生成带精度的DDL语句

更简便的实现方案

除了你自己实现的TypeDecorator,还有两种更轻量的实现方式:

  1. 使用Numeric/DECIMAL类型(最符合原生使用习惯)
    SQLAlchemy的Numeric类型原生支持scale参数指定保留小数位数,会自动帮你做精度截断,不需要额外自定义逻辑:
from sqlalchemy import Column, Numeric
# precision是数值总位数,scale是保留小数位数,asdecimal=False直接返回浮点数不需要额外转Decimal
perf = Column(Numeric(precision=10, scale=3, asdecimal=False))

这种写法和你之前期望的Float(3)用法几乎一致,是最简便的方案。

  1. 列级别事件监听
    如果不想改字段类型,可以给对应字段加set事件监听,赋值时自动做精度处理,不需要自定义类型也不需要改业务代码:
from sqlalchemy import event
from your_module import YourModel

@event.listens_for(YourModel.perf, 'set')
def auto_round_perf(target, value, oldvalue, initiator):
    return round(value, 3) if value is not None else value

关于你实现的TypeDecorator的说明

你自己写的PrecisionFloat其实不是冗余实现,而是SQLAlchemy官方推荐的自定义类型标准写法,如果你项目里有多个字段需要统一配置精度,这个自定义类型的复用性更高,反而比每个字段单独配置更高效,完全符合最佳实践。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 20:45:05