[Django] #36096: QuerySet.values() on a UNION query results in a broken query

7 views
Skip to first unread message

Django

unread,
Jan 13, 2025, 10:39:55 PM1/13/25
to django-...@googlegroups.com
#36096: QuerySet.values() on a UNION query results in a broken query
-------------------------------------+-------------------------------------
Reporter: Isaac Nygaard | Type:
| Uncategorized
Status: new | Component: Database
| layer (models, ORM)
Version: 5.0 | Severity: Normal
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
When calling `QuerySet.values()` on a union query, I get some internal
Django errors. For example:

{{{
qs = model.values(*grouping).annotate(**annotations)

// SAMPLE A: the following raises internal Django errors
t1 = qs.annotate(time_period=Value(1)).filter(filter_1)
t2 = qs.annotate(time_period=Value(2)).filter(filter_2)
qs = t1.union(t2).values(*values)

// SAMPLE B: the following works
t1 = qs.annotate(time_period=Value(1)).filter(filter_1).values(*values)
t2 = qs.annotate(time_period=Value(2)).filter(filter_2).values(*values)
qs = t1.union(t2)
}}}

Sample A fails because `qs.annotation_select` becomes different from
`t1.annotation_select` and `t2.annotation_select`. Django doesn't complain
until the query is run, and the database returns different columns (or
columns in a different order) than what it was expecting.

I would think Django should do one of the following:
1. have `qs.values()` update the selected annotations for its two child
combinator queries, t1/t2 (this is what I expected and why I wrote the
code that way)
2. disallow `values()` on union queries, e.g. by raising an informative
error
3. detect that `qs.annotation_select` columns do not match
`annotation_select` of the two child combinator queries and raise an
informative error
--
Ticket URL: <https://code.djangoproject.com/ticket/36096>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Jan 14, 2025, 1:19:04 AM1/14/25
to django-...@googlegroups.com
#36096: QuerySet.values() on a UNION query results in a broken query
-------------------------------------+-------------------------------------
Reporter: Isaac Nygaard | Owner: (none)
Type: Uncategorized | Status: closed
Component: Database layer | Version: 5.0
(models, ORM) |
Severity: Normal | Resolution: invalid
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Simon Charette):

* cc: Simon Charette (added)
* resolution: => invalid
* status: new => closed

Comment:

There was a significant refactor to how `values` operates with regards to
the order of the `SELECT` clause
[https://github.com/django/django/pull/16703/ that landed a few weeks ago
to address issues] with `union` involving annotations (see #28900) which
will be part of [https://code.djangoproject.com/wiki/Version5.2Roadmap the
5.2 alpha release] schedule to be released soon.

I suspect
[https://github.com/django/django/pull/16703/commits/70e8983c3be17e7532defa915ae5ce5b9ad5c1e6
this commit will address your issue] but you've unfortunately not provided
enough details in your report (exact models) for us to determine if it's
the case. I suggest you test whether or not the current `main` branch
resolves your issue (or wait for 5.2a1 to be released and test against it)
and re-open if applicable.
--
Ticket URL: <https://code.djangoproject.com/ticket/36096#comment:1>
Reply all
Reply to author
Forward
0 new messages