[Django] #34931: QuerySet .count() crashes when queryset contains FilteredRelation referencing annotation in condition

16 views
Skip to first unread message

Django

unread,
Oct 26, 2023, 2:28:49 PM10/26/23
to django-...@googlegroups.com
#34931: QuerySet .count() crashes when queryset contains FilteredRelation
referencing annotation in condition
-------------------------------------+-------------------------------------
Reporter: Ben Nace | Owner: nobody
Type: Bug | Status: new
Component: Database | Version: 4.2
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 |
-------------------------------------+-------------------------------------
With the following models:

{{{
from django.db import models


class ModelA(models.Model):
threshold1 = models.PositiveIntegerField()
threshold2 = models.PositiveIntegerField()


class ModelB(models.Model):
model_a = models.ForeignKey(ModelA, on_delete=models.CASCADE)
value = models.IntegerField()
}}}

Attempting the following query results in a FieldError:

{{{
from django.db.models import F, FilteredRelation, Q
ModelA.objects.annotate(combined_threshold=F('threshold1') +
F('threshold2'), filtered_b=FilteredRelation('modelb',
condition=Q(modelb__value__gte=F('combined_threshold')))).values('filtered_b__value').count()
}}}

{{{
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/home/bnace/python-envs/pmcs-42/lib/python3.9/site-
packages/django/db/models/query.py", line 608, in count
return self.query.get_count(using=self.db)
File "/home/bnace/python-envs/pmcs-42/lib/python3.9/site-
packages/django/db/models/sql/query.py", line 568, in get_count
return obj.get_aggregation(using, {"__count": Count("*")})["__count"]
File "/home/bnace/python-envs/pmcs-42/lib/python3.9/site-
packages/django/db/models/sql/query.py", line 554, in get_aggregation
result = compiler.execute_sql(SINGLE)
File "/home/bnace/python-envs/pmcs-42/lib/python3.9/site-
packages/django/db/models/sql/compiler.py", line 1549, in execute_sql
sql, params = self.as_sql()
File "/home/bnace/python-envs/pmcs-42/lib/python3.9/site-
packages/django/db/models/sql/compiler.py", line 761, in as_sql
from_, f_params = self.get_from_clause()
File "/home/bnace/python-envs/pmcs-42/lib/python3.9/site-
packages/django/db/models/sql/compiler.py", line 1128, in get_from_clause
clause_sql, clause_params = self.compile(from_clause)
File "/home/bnace/python-envs/pmcs-42/lib/python3.9/site-
packages/django/db/models/sql/compiler.py", line 546, in compile
sql, params = node.as_sql(self, self.connection)
File "/home/bnace/python-envs/pmcs-42/lib/python3.9/site-
packages/django/db/models/sql/datastructures.py", line 105, in as_sql
extra_sql, extra_params = compiler.compile(self.filtered_relation)
File "/home/bnace/python-envs/pmcs-42/lib/python3.9/site-
packages/django/db/models/sql/compiler.py", line 546, in compile
sql, params = node.as_sql(self, self.connection)
File "/home/bnace/python-envs/pmcs-42/lib/python3.9/site-
packages/django/db/models/query_utils.py", line 434, in as_sql
where = query.build_filtered_relation_q(self.condition,
reuse=set(self.path))
File "/home/bnace/python-envs/pmcs-42/lib/python3.9/site-
packages/django/db/models/sql/query.py", line 1609, in
build_filtered_relation_q
child_clause, _ = self.build_filter(
File "/home/bnace/python-envs/pmcs-42/lib/python3.9/site-
packages/django/db/models/sql/query.py", line 1435, in build_filter
value = self.resolve_lookup_value(value, can_reuse, allow_joins)
File "/home/bnace/python-envs/pmcs-42/lib/python3.9/site-
packages/django/db/models/sql/query.py", line 1204, in
resolve_lookup_value
value = value.resolve_expression(
File "/home/bnace/python-envs/pmcs-42/lib/python3.9/site-
packages/django/db/models/expressions.py", line 822, in resolve_expression
return query.resolve_ref(self.name, allow_joins, reuse, summarize)
File "/home/bnace/python-envs/pmcs-42/lib/python3.9/site-
packages/django/db/models/sql/query.py", line 1976, in resolve_ref
join_info = self.setup_joins(
File "/home/bnace/python-envs/pmcs-42/lib/python3.9/site-
packages/django/db/models/sql/query.py", line 1823, in setup_joins
path, final_field, targets, rest = self.names_to_path(
File "/home/bnace/python-envs/pmcs-42/lib/python3.9/site-
packages/django/db/models/sql/query.py", line 1724, in names_to_path
raise FieldError(
django.core.exceptions.FieldError: Cannot resolve keyword
'combined_threshold' into field. Choices are: __count, filtered_b, id,
modelb, threshold1, threshold2
}}}

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

Django

unread,
Oct 26, 2023, 2:46:25 PM10/26/23
to django-...@googlegroups.com
#34931: QuerySet .count() crashes when queryset contains FilteredRelation
referencing annotation in condition
-------------------------------------+-------------------------------------
Reporter: Ben Nace | Owner: nobody
Type: Bug | Status: closed
Component: Database layer | Version: 4.2
(models, ORM) |
Severity: Normal | Resolution: duplicate
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 Mariusz Felisiak):

* status: new => closed
* resolution: => duplicate


Comment:

Duplicate of #33766, fixed in d660cee5bc68b597503c2a16f3d9928d52f93fb4
(Django 5.0+).

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

Reply all
Reply to author
Forward
0 new messages