[Django] #26650: output_field key-word arg not respected in model query API

9 views
Skip to first unread message

Django

unread,
May 22, 2016, 9:36:31 PM5/22/16
to django-...@googlegroups.com
#26650: output_field key-word arg not respected in model query API
-------------------------------------+-------------------------------------
Reporter: freshquiz | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: master
(models, ORM) | Keywords: output_field expression
Severity: Normal | query annotate aggregate
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Given the following model:
{{{
import django.db.models

class TempModel(django.db.models.Model):
field1 = django.db.models.DecimalField(max_digits=12,
decimal_places=2)
}}}
...when I run a query like so:
{{{
TempModel.objects.all().aggregate(
my_sum=django.db.models.Sum(
'field1', output_field=django.db.models.DateTimeField()
)
)
}}}
...the result produces a `Decimal` result, no matter what `output_field`
is specified.

I came across this issue by simply wanting to specify the number of
decimal places that would get output in queries such as this.
That led me to find #23941, which shocked me in seeing that the "sane"
behaviour/implementation was replaced with something that breaks
down/invalidates the API.

Then I tried the query above, with all different kinds of `output_field`
values and realised the problem is more systemic and severe, in the sense
that specifying `output_field` is often pointless/futile.

Why can't the implementation actually honour the `output_field` parameter
and construct SQL to cast/coerce fields into the appropriate DB field
types?

The only other means (in which I am aware of) for ensuring that a query
gets compiled to SQL that honours the clients' field type specifications
is to use `.extra()` or `.raw()`, but then that is no longer DB agnostic.
I would have thought it was the job of `output_field` to achieve this in a
DB agnostic manner, utilising the power of the ORM.

--
Ticket URL: <https://code.djangoproject.com/ticket/26650>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
May 22, 2016, 9:45:07 PM5/22/16
to django-...@googlegroups.com
#26650: output_field key-word arg not respected in model query API
-------------------------------------+-------------------------------------
Reporter: freshquiz | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: master
(models, ORM) |
Severity: Normal | Resolution:
Keywords: output_field | Triage Stage:
expression query annotate | Unreviewed
aggregate |
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by charettes):

* needs_better_patch: => 0
* needs_tests: => 0
* needs_docs: => 0


Comment:

Did you try using the recently introduced `Cast()`
[https://docs.djangoproject.com/en/dev/ref/models/database-functions/#cast
expression]?

{{{#!python
TempModel.objects.aggregate(
my_sum=Cast(Sum('field1'), DecimalField(max_digits=30,
decimal_places=2)),
)
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/26650#comment:1>

Django

unread,
May 22, 2016, 9:59:18 PM5/22/16
to django-...@googlegroups.com
#26650: output_field key-word arg not respected in model query API
-------------------------------------+-------------------------------------
Reporter: freshquiz | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: master
(models, ORM) |
Severity: Normal | Resolution:
Keywords: output_field | Triage Stage:
expression query annotate | Unreviewed
aggregate |
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by freshquiz):

Thank you, I was not aware of the feature.

`Cast()` does address my issue.

So it appears that instead of respecting `output_field` as I proposed in
the description of this ticket, the implementation has just tacked on more
API, rather than refactoring the implementation of the existing API.

If the core devs are happy travelling down this path, I guess this ticket
has nothing further to offer and hence can be closed.

--
Ticket URL: <https://code.djangoproject.com/ticket/26650#comment:2>

Django

unread,
May 22, 2016, 10:04:39 PM5/22/16
to django-...@googlegroups.com
#26650: output_field key-word arg not respected in model query API
-------------------------------------+-------------------------------------
Reporter: freshquiz | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: master
(models, ORM) |
Severity: Normal | Resolution:
Keywords: output_field | Triage Stage:
expression query annotate | Unreviewed
aggregate |
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by charettes):

I guess it could be worth investigating if a `Cast` should be added when
an `output_field` is explicitly specified.

--
Ticket URL: <https://code.djangoproject.com/ticket/26650#comment:3>

Django

unread,
May 22, 2016, 10:30:58 PM5/22/16
to django-...@googlegroups.com
#26650: output_field key-word arg not respected in model query API
-------------------------------------+-------------------------------------
Reporter: freshquiz | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: master
(models, ORM) |
Severity: Normal | Resolution:
Keywords: output_field | Triage Stage:
expression query annotate | Unreviewed
aggregate |
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by freshquiz):

My suggestion would be to use the implementation of `Cast()` everywhere
that `output_field` is used and to get rid of `Cast()` from the public
API.

I.e. Why does `Cast()` have to be restricted to SQL functions?

--
Ticket URL: <https://code.djangoproject.com/ticket/26650#comment:4>

Django

unread,
May 28, 2016, 12:10:16 PM5/28/16
to django-...@googlegroups.com
#26650: Automatically apply Cast based on output_field

-------------------------------------+-------------------------------------
Reporter: freshquiz | Owner: nobody
Type: | Status: new
Cleanup/optimization |

Component: Database layer | Version: master
(models, ORM) |
Severity: Normal | Resolution:
Keywords: output_field | Triage Stage: Accepted
expression query annotate |

aggregate |
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by timgraham):

* type: Bug => Cleanup/optimization
* stage: Unreviewed => Accepted


Comment:

Accepting for further investigation.

--
Ticket URL: <https://code.djangoproject.com/ticket/26650#comment:5>

Django

unread,
Dec 13, 2017, 12:18:11 PM12/13/17
to django-...@googlegroups.com
#26650: Automatically apply Cast based on output_field
-------------------------------------+-------------------------------------
Reporter: Matt C | Owner: nobody
Type: | Status: new
Cleanup/optimization |

Component: Database layer | Version: master
(models, ORM) |
Severity: Normal | Resolution:
Keywords: output_field | Triage Stage: Accepted
expression query annotate |
aggregate |
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Sergey Fedoseev):

* cc: Sergey Fedoseev (added)


--
Ticket URL: <https://code.djangoproject.com/ticket/26650#comment:6>

Reply all
Reply to author
Forward
0 new messages