Opened 53 minutes ago
#37454 new Uncategorized
Should DecimalField on postgresql adapt its values?
| Reported by: | Julien Palard | Owned by: | |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | 6.1 |
| Severity: | Normal | Keywords: | |
| Cc: | Julien Palard | Triage Stage: | Unreviewed |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
Currently the DecimalField values are not adapted:
def adapt_decimalfield_value(self, value, max_digits=None, decimal_places=None):
"""
Transform a decimal.Decimal value to an object compatible with what is
expected by the backend driver for decimal (numeric) columns.
"""
return value
Say I use:
class Doh(models.Model):
cost = models.DecimalField("cost", max_digits=9, decimal_places=3)
Then it behave surprisingly at request time:
$ ./manage.py shell
>>> from decimal import Decimal
>>> kwargs = {"cost": Decimal("12345.123456789")}
>>> Doh.objects.create(**kwargs)
<Doh: Doh object (1)>
>>> Doh.objects.get(**kwargs)
Traceback (most recent call last):
[...]
app.models.Doh.DoesNotExist: Doh matching query does not exist.
So currently I'm using:
with localcontext() as ctx:
ctx.rounding = ROUND_UP
kwargs = {"cost": round(Decimal("12345.123456789"), 3)}
But it feels fragile: what if I change the scale on the model side? I'll have to change all my calls to round.
Also it feels like implementing something that could be done in the adapter: if we know the decimal has only 3 places, allowing a request to touch the database with a WHERE with a value with more prevision will always result in no answer from the DB so there’s no point? Or am I missing something?