使用Django DecimalField和PostgreSql数字字段保持输出精度

时间:2011-09-06 04:27:01

标签: django postgresql precision

我正在通过Django将数据保存到PostgreSQL后端。我的模型中的许多字段都是DecimalFields设置为任意高的max_digits和decimal_places,对应于数据库后端中的数字列。每列中的数据具有未知先验的精度(或小数位数),并且给定列中的每个数据不需要具有相同的精度。

例如,模型的参数可能如下所示:

{'dist': Decimal("94.3"), 'dist_e': Decimal("1.2")}
{'dist': Decimal("117"), 'dist_e': Decimal("4")}

其中键是数据库列名。

输出后,我需要以读取它们的精度保留和重新显示这些数据。换句话说,在查询数据库之后,显示的数据看起来应该与读入的数据完全相同,没有额外或缺少小数的尾随0。但是,当在django shell或admin界面中查询时,所有DecimalField数据都会返回许多尾随0。

我已经看到类似的问题已经回答金钱价值,其中精确度(2位小数)是已知的,并且对于给定列中的所有数据都是相同的。但是,当精度不相同且事先不知道时,如何最好地保留Django中的Decimal值和PostgreSQL中的数值所表示的精确精度?

编辑:

可能是另一个有用的信息:当在Django dbshel​​l中查看保存数据的表时,也会出现许多尾随0。在保存到PostgreSQL后端时,python Decimal值显然转换为models.py文件中指定的最大精度值。

2 个答案:

答案 0 :(得分:2)

如果您需要向前和向后完美平价,则需要使用CharField。任何基于数字的数据库字段都将以某种方式与您的数据进行交互。现在,我知道你提到无法知道数据点的数字长度,而CharField需要一些长度。您可以将其设置为任意高(1000,2000等),或者我认为您可以使用TextField。

但是,无论采用哪种方法,在大多数情况下,您都会浪费大量数据库资源。我建议修改你的方法,使得最后的额外零无关紧要(为了显示目的,你总是可以将它们切掉),或者精度不再是任意的。

答案 1 :(得分:1)

由于我前一段时间问过这个问题并且答案保持不变,我会分享我发现的,如果它对任何处于类似位置的人有帮助。 Django没有能力以任意精度利用PostgreSQL数字列类型。为了保持我上传到我的数据库的数据的显示精度,并且为了能够对从数据库查询获得的值执行数学计算而不首先将字符串重新编码为python Decimal类型,我选择为每个数据库添加额外的精度列数据库中的数字列。

精度值是一个整数,表示小数点后需要多少位数。基准4.350在其对应的精度列中分配了值3。通常显示的整数(例如2531)具有0的精度条目。但是,以科学记数法报告的大整数被赋予负整数以保持其显示精度。例如,值4.320E+33获取精度条目-3。数据库识别出所有具有负精度值的对象应以科学计数法重新显示。

此解决方案为数据库周围的结构和代码增加了一些复杂性,但事实证明它有效。它还允许我通过计算准确地保持精度,例如转换为/从对数和线性值。