[Django] #34024: 'WhereNode' object has no attribute 'is_summary' when counting a queryset with annotation from a subquery

270 views
Skip to first unread message

Django

unread,
Sep 20, 2022, 9:31:02 AM9/20/22
to django-...@googlegroups.com
#34024: 'WhereNode' object has no attribute 'is_summary' when counting a queryset
with annotation from a subquery
-------------------------------------+-------------------------------------
Reporter: vrigal | Owner: nobody
Type: Bug | Status: new
Component: Database | Version: 4.1
layer (models, ORM) |
Severity: Normal | Keywords:
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
I reproduced on a blank project (4.0 and 4.1 with a Postgres database)
using this use case:

`models.py`
{{{
class School(models.Model):
"""A school"""

class Director(models.Model):
school = models.ForeignKey(School, on_delete=models.CASCADE)
speciality = models.CharField(max_length=200)
}}}

It is not possible to run this code:
{{{#!python
>>> School.objects.annotate(
>>> speciality=Subquery(Director.objects.values('speciality')[:1]),
>>> has_speciality=Q(speciality__isnull=False)
>>> ).count()

AttributeError: 'WhereNode' object has no attribute 'is_summary'
}}}

Reverting this precise commit seems to fix the issue :
https://github.com/django/django/commit/b64db05b9cedd96905d637a2d824cbbf428e40e7

The request is a bit exotic, I don't know if it should be supported.
This is the first ticket I open, I can clarify/submit a merge request if
needed.

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

Django

unread,
Sep 20, 2022, 1:24:11 PM9/20/22
to django-...@googlegroups.com
#34024: 'WhereNode' object has no attribute 'is_summary' when counting a queryset
with annotation from a subquery
-------------------------------------+-------------------------------------
Reporter: Valentin Rigal | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 4.1
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by David Sanders):

Confirmed on latest main.

Full traceback from ipython:

{{{
[ins] In [1]: School.objects.annotate(
...:


speciality=Subquery(Director.objects.values('speciality')[:1]),

...: has_speciality=Q(speciality__isnull=False)
...: ).count()
---------------------------------------------------------------------------
AttributeError Traceback (most recent call
last)
Cell In [1], line 4
1 School.objects.annotate(
2


speciality=Subquery(Director.objects.values('speciality')[:1]),

3 has_speciality=Q(speciality__isnull=False)
----> 4 ).count()

File ~/projects/django/django/db/models/query.py:621, in
QuerySet.count(self)
618 if self._result_cache is not None:
619 return len(self._result_cache)
--> 621 return self.query.get_count(using=self.db)

File ~/projects/django/django/db/models/sql/query.py:554, in
Query.get_count(self, using)
552 obj = self.clone()
553 obj.add_annotation(Count("*"), alias="__count", is_summary=True)
--> 554 return obj.get_aggregation(using, ["__count"])["__count"]

File ~/projects/django/django/db/models/sql/query.py:503, in
Query.get_aggregation(self, using, added_aggregate_names)
501 for alias, expression in
list(inner_query.annotation_select.items()):
502 annotation_select_mask = inner_query.annotation_select_mask
--> 503 if expression.is_summary:
504 expression, col_cnt = inner_query.rewrite_cols(expression,
col_cnt)
505 outer_query.annotations[alias] =
expression.relabeled_clone(
506 relabels
507 )

AttributeError: 'WhereNode' object has no attribute 'is_summary'
}}}

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

Django

unread,
Sep 20, 2022, 1:26:13 PM9/20/22
to django-...@googlegroups.com
#34024: 'WhereNode' object has no attribute 'is_summary' when counting a queryset
with annotation from a subquery
-------------------------------------+-------------------------------------
Reporter: Valentin Rigal | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 4.1
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted

Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Simon Charette):

* stage: Unreviewed => Accepted


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

Django

unread,
Sep 20, 2022, 3:59:41 PM9/20/22
to django-...@googlegroups.com
#34024: 'WhereNode' object has no attribute 'is_summary' when counting a queryset
with annotation from a subquery
-------------------------------------+-------------------------------------
Reporter: Valentin Rigal | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 4.1
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by David Sanders):

* cc: David Sanders (added)


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

Django

unread,
Sep 21, 2022, 6:44:06 AM9/21/22
to django-...@googlegroups.com
#34024: 'WhereNode' object has no attribute 'is_summary' when counting a queryset
with annotation from a subquery
-------------------------------------+-------------------------------------
Reporter: Valentin Rigal | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 4.1
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by David Sanders):

Here's a simple boiled down failing test case:

{{{
diff --git a/tests/queries/tests.py b/tests/queries/tests.py
index 1bd72dd8b8..c6d9b05761 100644
--- a/tests/queries/tests.py
+++ b/tests/queries/tests.py
@@ -1312,6 +1312,10 @@ class Queries1Tests(TestCase):
)
self.assertSequenceEqual(Note.objects.exclude(negate=True),
[self.n3])

+ def test_count_on_annotation(self):
+ # Ticket: #34024
+ Tag.objects.annotate(has_pk=~Q(pk=None)).count()
+

class Queries2Tests(TestCase):
@classmethod
}}}

results

{{{
E
======================================================================
ERROR: test_count_on_annotation (queries.tests.Queries1Tests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/davids/projects/django/tests/queries/tests.py", line 1317,
in test_count_on_annotation
Tag.objects.annotate(has_pk=~Q(pk=None)).count()
File "/Users/davids/projects/django/django/db/models/query.py", line
621, in count
return self.query.get_count(using=self.db)
File "/Users/davids/projects/django/django/db/models/sql/query.py", line
554, in get_count


return obj.get_aggregation(using, ["__count"])["__count"]

File "/Users/davids/projects/django/django/db/models/sql/query.py", line
503, in get_aggregation
if expression.is_summary:
AttributeError: 'WhereNode' object has no attribute 'is_summary'

----------------------------------------------------------------------
Ran 1 test in 0.014s

FAILED (errors=1)
Destroying test database for alias 'default'...
}}}

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

Django

unread,
Sep 21, 2022, 2:25:14 PM9/21/22
to django-...@googlegroups.com
#34024: 'WhereNode' object has no attribute 'is_summary' when counting a queryset
with annotation from a subquery
-------------------------------------+-------------------------------------
Reporter: Valentin Rigal | Owner: David
| Sanders
Type: Bug | Status: assigned

Component: Database layer | Version: 4.1
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by David Wobrock):

* cc: David Wobrock (added)
* owner: nobody => David Sanders
* has_patch: 0 => 1
* status: new => assigned


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

Django

unread,
Sep 23, 2022, 10:16:13 AM9/23/22
to django-...@googlegroups.com
#34024: 'WhereNode' object has no attribute 'is_summary' when counting a queryset
with annotation from a subquery
-------------------------------------+-------------------------------------
Reporter: Valentin Rigal | Owner: David
| Sanders
Type: Bug | Status: closed

Component: Database layer | Version: 4.1
(models, ORM) |
Severity: Normal | Resolution: fixed

Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by GitHub <noreply@…>):

* status: assigned => closed
* resolution: => fixed


Comment:

In [changeset:"1674c70525bc370132a1db27617e468081920d11" 1674c705]:
{{{
#!CommitTicketReference repository=""
revision="1674c70525bc370132a1db27617e468081920d11"
Fixed #34024 -- Fixed crash when aggregating querysets with Q objects
annotations.

This reverts b64db05b9cedd96905d637a2d824cbbf428e40e7.

It was reasonable to assume it was unnecessary code as there were
no failing tests upon its removal. This commit adds the necessary
regression tests for the failing condition identified in #34024
alongside the original tests added in the PR for which
WhereNode.is_summary was introduced.
}}}

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

Reply all
Reply to author
Forward
0 new messages