0

从 3.1 版本升级到 3.2 版本后,我发现使用小数字段的精度问题。以下示例是一个可以重新生成问题的小代码。

from django.db import models

class Foo(models.Model):
    amount = models.DecimalField(
        null=False,
        decimal_places=18,
        max_digits=44)


# A simple insertion example 
from api.models import Foo
from django.db.models import F
from decimal import Decimal

f = Foo.objects.create(amount=Decimal('0.5'))
f.amount = F('amount') - Decimal('0.4')
f.save(update_fields=['amount', ])
f.refresh_from_db()
print(f.amount)

此代码生成0.099999999999999980但之前版本中的相同代码生成预期结果0.01。通过检查为更新查询生成的mysql查询,我发现在新版本号中已使用报价发送,但在以前的版本中没有报价。即在新版本中我们有这样的东西,UPDATE `api_foo` SET `amount` = (`api_foo`.`amount` - '0.4') WHERE `api_foo`.`id` = 1但在以前的版本中我们有UPDATE `api_foo` SET `amount` = (`api_foo`.`amount` - 0.4) WHERE `api_foo`.`id` = 1。另外我必须提到,这仅发生在 mysql 驱动程序中,而不是 sqllite 中。

我知道这似乎是一个错误,但我猜我错过了一些微不足道的东西。

我正在使用 mysql-8.0.19,并且在 django 的 3.2 和 3.2.3 版本中得到了相同的值。

4

0 回答 0