#28900: QuerySet.values() and values_list() for union(), difference(), and
intersection() queries fails with annotated subquery
-------------------------------------+-------------------------------------
Reporter: elliott- | Owner: nobody
omosheye |
Type: Bug | Status: new
Component: Database | Version: 1.11
layer (models, ORM) |
Severity: Normal | Keywords: union, values
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
Added failing test to demonstrate
{{{
def test_union_values_subquery(self):
items = Item.objects.filter(creator=OuterRef("pk"))
item_authors =
Author.objects.annotate(is_creator=Exists(items)).order_by()
reports = Report.objects.filter(creator=OuterRef("pk"))
report_authors =
Author.objects.annotate(is_creator=Exists(reports)).order_by()
all_authors = item_authors.union(report_authors).order_by()
self.assertEqual(list(all_authors.values_list("is_creator",
flat=True)), [True, True, True, True])
}}}
silently messes up the data on values/values_list() with an field
{{{
FAIL: test_union_values_subquery (queries.tests.Queries1Tests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/usr/local/lib/python2.7/unittest/case.py", line 329, in run
testMethod()
File "/usr/src/widget_app/tests/queries/tests.py", line 95, in
test_union_values_subquery
self.assertEqual(list(all_authors.values_list("is_creator",
flat=True)), [True, True, True, True])
File "/usr/local/lib/python2.7/unittest/case.py", line 513, in
assertEqual
assertion_func(first, second, msg=msg)
File "/usr/local/lib/python2.7/unittest/case.py", line 742, in
assertListEqual
self.assertSequenceEqual(list1, list2, msg, seq_type=list)
File "/usr/local/lib/python2.7/unittest/case.py", line 724, in
assertSequenceEqual
self.fail(msg)
File "/usr/local/lib/python2.7/unittest/case.py", line 410, in fail
raise self.failureException(msg)
AssertionError: Lists differ: [True, True, 2, 2, 3, 4, 4] != [True, True,
True, True]
First differing element 2:
2
True
First list contains 3 additional elements.
First extra element 4:
3
- [True, True, 2, 2, 3, 4, 4]
+ [True, True, True, True]
}}}
throws error on empty values()/values_list()
{{{
Traceback (most recent call last):
File "/usr/local/lib/python2.7/unittest/case.py", line 329, in run
testMethod()
File "/usr/src/widget_app/tests/queries/tests.py", line 95, in
test_union_values_subquery
self.assertEqual(list(all_authors.values()), [True, True, True, True])
File "/usr/local/lib/python2.7/site-packages/django/db/models/query.py",
line 250, in __iter__
self._fetch_all()
File "/usr/local/lib/python2.7/site-packages/django/db/models/query.py",
line 1118, in _fetch_all
self._result_cache = list(self._iterable_class(self))
File "/usr/local/lib/python2.7/site-packages/django/db/models/query.py",
line 106, in __iter__
for row in compiler.results_iter(chunked_fetch=self.chunked_fetch):
File "/usr/local/lib/python2.7/site-
packages/django/db/models/sql/compiler.py", line 847, in results_iter
row = self.apply_converters(row, converters)
File "/usr/local/lib/python2.7/site-
packages/django/db/models/sql/compiler.py", line 830, in apply_converters
value = row[pos]
IndexError: list index out of range
}}}
The funny thing is that the produced SQL query is perfectly valid, so it
isn't a case of me asking the ORM to do something especially funky. In any
case if this is an unsupported action then the ORM should tell you and not
produce runtime errors or silently return bad data.
--
Ticket URL: <https://code.djangoproject.com/ticket/28900>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/059.3800c2cf2d568e7e1a26808659032338%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.