5

我正在编写一个 web2py 应用程序,该应用程序需要对美元金额求和而不会丢失精度。我意识到我需要为此使用小数,但我发现自己必须将我从数据库中获得的每个数字包装起来:

Decimal(str(myval))

在我疯狂地将它添加到我的所有代码之前,有没有更好的方法?我是 Python 新手,所以我很可能忽略了一些明显的东西。

编辑:我的数据库是 MS SQL Server,我将金额存储在 SQL Servermoney字段中(我相信实现类似于 Decimal,即整数数学,而不是浮点数)。

我通过 web2py 框架(pyodbc用于 SQL Server 连接)连接到数据库。我相信 web2py 对十进制类型有一些支持。例如,我的 web2py 字段定义如下所示:Field('Amount','decimal(19,4)') 但是,当我使用 web2py 的.executesql方法从数据库返回一个值时,它返回的值是 afloat而不是 a Decimal

编辑:这似乎是 FreeTDS 和 MS SQL Server 的问题。正如 Massimo 在评论中所说,web2py 正确支持这一点并返回一个 Decimal (如果可以的话)。事实证明,这只是我的生产环境(Linux)中的一个问题。我正在使用 FreeTDS 驱动程序连接到 MS SQL,它似乎正在将 MS SQL 货币类型转换为 python 浮点数。

我认为 Alex Martelli 的回答指向了正确的方向。有人对 FreeTDS、MS SQL 和 python 有任何经验吗?我认为这可能需要它自己的问题,所以我会移动这个讨论......(这里发布的新问题:FreeTDS translate MS SQL money type to python float, not Decimal

更新:实际上 FreeTDS 中存在一个错误。截至 2010 年 8 月 4 日, 此问题已在 FreeTDS 的 CVS 负责人中修复。

4

2 回答 2

8

首先,在数据库中保留所有数字的十进制形式——你没有提到你正在使用什么数据库引擎,但是每个引擎都支持这样的功能,例如,这里是 MySQL 的DECIMAL类型文档。我希望您已经这样做了,但是,如果您没有这样做,那么架构更改的痛苦仍然值得。

然后,您需要确保与数据库的类型转换与数据库的小数点与 Python 的小数点相匹配。不幸的是,没有跨 DB-API 实现的标准方法,但大多数都提供了一种方法;例如,对于 MySQLDB,您需要传递一个conv=参数 in connect,称为“类型转换器字典”——默认是副本,MySQLdb.converters.conversions但当然您可以丰富它以使用小数做正确的事情。如果您告诉我们您正在使用哪个 DB,以及您更喜欢哪个 DB-API 连接器包,我们可能会在此主题上为您提供更详细的帮助。

编辑:@unutbu 在评论中指出当前 MySQLdb 转换器已经正确转换小数,因此,除非您使用非常旧的 MySQLdb 版本,否则只要您正确地将所有数字保留为小数,您应该没问题在数据库中(耶!)。

于 2010-07-29T16:57:46.537 回答
0

您可以编写一个函数,该函数既从数据库中获取数字,然后将其转换为十进制。然后在你的代码中使用它。

于 2010-07-29T16:40:48.213 回答