SQLModel 中的 Decimal 类型:精确处理金融数据的最佳实践

SQLModel 中的 Decimal 类型:精确处理金融数据的最佳实践

sqlmodel SQL databases in Python, designed for simplicity, compatibility, and robustness. sqlmodel 项目地址: https://gitcode.com/gh_mirrors/sq/sqlmodel

为什么需要 Decimal 类型

在编程中处理金融数据时,浮点数的精度问题常常让人头疼。例如在 Python 中执行 1.1 + 2.2 时,期望得到 3.3,实际却得到 3.3000000000000003。这种精度问题源于计算机使用二进制存储浮点数的本质。

对于以下场景,这种精度损失是不可接受的:

  • 金融交易系统
  • 会计软件
  • 电子商务平台的价格计算
  • 任何需要精确计算的货币操作

SQLModel 中的 Decimal 解决方案

SQLModel 基于 Pydantic 和 SQLAlchemy,提供了完善的 Decimal 类型支持,可以完美解决上述精度问题。

基本用法

在 SQLModel 模型中定义 Decimal 字段:

from decimal import Decimal
from sqlmodel import SQLModel, Field
from sqlmodel.sql.sqltypes import AutoString

class Hero(SQLModel, table=True):
    id: int | None = Field(default=None, primary_key=True)
    name: str
    secret_name: str
    age: int | None = None
    money: Decimal = Field(max_digits=5, decimal_places=3)

这里我们定义了一个 money 字段,参数说明:

  • max_digits=5:总位数(整数部分+小数部分)
  • decimal_places=3:小数位数

有效值示例

根据上述定义,以下数值是有效的:

  • 12.345
  • 12.3
  • 12
  • 1.2
  • 0.123
  • 0

无效值示例

以下数值将引发验证错误:

  • 1.2345(小数位数超过3位)
  • 123.234(总位数超过5位)
  • 123(整数部分超过2位)

实际应用示例

创建包含 Decimal 的记录

hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson", money=1.1)
hero_2 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48, money=2.2)

虽然我们传入的是浮点数,但 Pydantic 会自动将其转换为 Decimal 类型。

查询和计算

session.add(hero_1)
session.add(hero_2)
session.commit()

heroes = session.exec(select(Hero)).all()
total = sum(hero.money for hero in heroes)
print(f"Total money: {total}")

输出结果将是精确的 3.300,而不是浮点数计算常见的 3.3000000000000003。

数据库支持说明

需要注意的是,虽然 SQLModel 在 Python 层面完全支持 Decimal 类型,但底层数据库的支持情况有所不同:

  • PostgreSQL、MySQL 等主流数据库原生支持 Decimal 类型
  • SQLite 会将 Decimal 转换为它支持的 NUMERIC 类型(本质仍是浮点数)

对于生产环境的金融应用,建议使用 PostgreSQL 等专业数据库系统。

最佳实践建议

  1. 根据业务需求合理设置精度:

    • 货币交易:通常需要 2-4 位小数
    • 科学计算:可能需要更高精度
  2. 避免在应用层进行浮点数计算,始终使用 Decimal 类型

  3. 在数据库迁移脚本中明确指定 Decimal 字段的精度

  4. 对于金融系统,考虑使用专门的货币处理库(如 python-money)

通过合理使用 SQLModel 的 Decimal 支持,开发者可以轻松构建出精确可靠的金融应用系统,避免因浮点数精度问题导致的业务逻辑错误。

sqlmodel SQL databases in Python, designed for simplicity, compatibility, and robustness. sqlmodel 项目地址: https://gitcode.com/gh_mirrors/sq/sqlmodel

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

胡晗研

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值