Opened 5 weeks ago
Last modified 4 days ago
#36030 assigned Bug
Expressions that divide an integer field by a constant decimal.Decimal returns inconsistent decimal places on PostgreSQL
Reported by: | Bartłomiej Nowak | Owned by: | Gregory Mariani |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 5.1 |
Severity: | Normal | Keywords: | |
Cc: | Bartłomiej Nowak | Triage Stage: | Accepted |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
When I am using Decimal at Python level, I expect to use numeric type on database level. But it seems to depend on string formatting of decimal itself instead of type of object.
See examples:
Decimal(1000.0)
--> will render as 1000
at query and will be INT on db level.
Decimal(1000)
--> will render as 1000
at query and will be INT on db level.
Decimal("1000.0")
-> will render as 1000,0
at query and will be NUMERIC on db level.
models.Value(1000.0, output_field=DecimalField())
-> will render as 1000
at query and will be INT on db level.
models.Value(1000.0)
(no decimal provided as above) -> will render as 1000,0
at query and will be NUMERIC on db level.
It leads to bugs, cuz at DB LVL, INT / INT is also INT (2/3 = 0), and I doubt anyone who provides decimal there, excepts that behavior.
=============
I am using Postgres.
SomeModel.objects.create(some_field_of_type_int=2) sm = SomeModel.objects.annotate(x=F("some_field_of_type_int") / Decimal(3.0)).get() sm.x # returns Decimal of 0
It will render Decimal of 3.0 to the query as 3 (INT). Because str(...) from Decimal(3.0) returns 3. (See cases at description)
At python is not a problem, but at database it is, cus it breaks types. Calculation of two INTs at postgres, will return int as well, which is in this case 0, instead of 0.6666, which database would produce, if Django would render 3.0 instead of 3.
Therefore, Django will return Decimal('0'), which I consider as Bug. This is not what anyone suppose to get.
=============
Change History (14)
comment:1 by , 5 weeks ago
comment:2 by , 5 weeks ago
Resolution: | → needsinfo |
---|---|
Status: | new → closed |
Closing as needsinfo
, Bartłomiej Nowak please reopen when you can provide further details as requested. A way to reproduce would be crucial. Thank you!
comment:3 by , 4 weeks ago
I am using Postgres.
SomeModel.objects.create(some_field_of_type_int=2) sm = SomeModel.objects.annotate(x=F("some_field_of_type_int") / Decimal(3.0)).get() sm.x # returns 0
It will render Decimal of 3.0 to the query as 3 (INT). Because str(...) from Decimal(3.0) returns 3. (See cases at description)
At python is not a problem, but at database it is, cus it breaks types. Calculation of two INTs at postgres, will return int as well, which is in this case 0, instead of 0.6666, which database would produce, if Django would render 3.0 instead of 3.
Therefore, Django will return Decimal('0'), which I consider as Bug. This is not what anyone suppose to get.
comment:4 by , 4 weeks ago
Description: | modified (diff) |
---|---|
Resolution: | needsinfo |
Status: | closed → new |
comment:5 by , 4 weeks ago
Description: | modified (diff) |
---|
comment:6 by , 4 weeks ago
Summary: | Rendering decimal to SQL is incoherent and leads to bugs. It relays on str formating not type. → Expressions that divide an integer field by a constant decimal.Decimal returns no inconsistent decimal places on PostgreSQL |
---|---|
Triage Stage: | Unreviewed → Accepted |
I was able to replicate. Note that when using Decimal("3.0")
it returns Decimal("0.66666666666666666666")
But when doing the same thing on SQLite, I consistently get Decimal("0")
I'm not sure what this _should_ do but I agree this is confusing and requires more investigation
Thank you for the ticket
comment:7 by , 4 weeks ago
Summary: | Expressions that divide an integer field by a constant decimal.Decimal returns no inconsistent decimal places on PostgreSQL → Expressions that divide an integer field by a constant decimal.Decimal returns inconsistent decimal places on PostgreSQL |
---|
follow-up: 12 comment:9 by , 4 weeks ago
Has patch: | set |
---|---|
Needs tests: | set |
Need help to create the tests. Have a patch to check
comment:10 by , 4 weeks ago
Has patch: | unset |
---|---|
Needs tests: | unset |
comment:11 by , 4 weeks ago
Has patch: | set |
---|
comment:12 by , 4 weeks ago
Needs documentation: | set |
---|---|
Needs tests: | set |
Owner: | set to |
Patch needs improvement: | set |
Status: | new → assigned |
comment:13 by , 4 days ago
Needs documentation: | unset |
---|---|
Needs tests: | unset |
Patch needs improvement: | unset |
Triage Stage: | Accepted → Ready for checkin |
comment:14 by , 4 days ago
Triage Stage: | Ready for checkin → Accepted |
---|
Hi Gregory, a reviewer must mark the ticket as "Ready for checkin" 🙂
Which database are you using? Can you give examples of the specific querysets and the expected results?