#36405: Aggregates with order_by using OuterRef raise FieldError -------------------------------------+------------------------------------- Reporter: Adam Johnson | Owner: Adam | Johnson Type: Bug | Status: assigned Component: Database layer | Version: 5.2 (models, ORM) | Severity: Release blocker | 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 Adam Johnson):
* version: dev => 5.2 Old description: > While fixing #36404, I spotted the same mistake had been made for the > newly added `Aggregate.order_by` from #35444. New description: While fixing #36404, I spotted the same mistake had been made for `Aggregate.order_by` (on `main`, from #35444), which was previously the PostgreSQL-specific `OrderableAggMixin.order_by` (on 5.2). The issue is reproduced in [https://github.com/adamchainz/django- ticket-36408 this example project], with models: {{{#!python from django.db import models class Book(models.Model): position = models.IntegerField() class Chapter(models.Model): book = models.ForeignKey(Book, on_delete=models.CASCADE) }}} And `QuerySet`: {{{#!python from django.contrib.postgres.aggregates import ArrayAgg from django.db.models import OuterRef, Subquery from example.models import Book, Chapter Book.objects.annotate( chapter_ids=Subquery( Chapter.objects.annotate( ids=ArrayAgg( "id", order_by=[OuterRef("position")], ) ).values("ids")[:1] ) ) }}} This error occurs: {{{ $ python t.py Traceback (most recent call last): File "/.../t.py", line 15, in <module> Chapter.objects.annotate( ~~~~~~~~~~~~~~~~~~~~~~~~^ ids=ArrayAgg( ^^^^^^^^^^^^^ ...<2 lines>... ) ^ ).values("ids")[:1] ^ File "/.../django/db/models/manager.py", line 87, in manager_method return getattr(self.get_queryset(), name)(*args, **kwargs) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^ File "/.../django/db/models/query.py", line 1647, in annotate return self._annotate(args, kwargs, select=True) ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/.../django/db/models/query.py", line 1699, in _annotate clone.query.add_annotation( ~~~~~~~~~~~~~~~~~~~~~~~~~~^ annotation, ^^^^^^^^^^^ alias, ^^^^^^ select=select, ^^^^^^^^^^^^^^ ) ^ File "/.../django/db/models/sql/query.py", line 1218, in add_annotation annotation = annotation.resolve_expression(self, allow_joins=True, reuse=None) File "/.../django/contrib/postgres/aggregates/mixins.py", line 33, in resolve_expression return super().resolve_expression(*args, **kwargs) ~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^ File "/.../django/db/models/aggregates.py", line 63, in resolve_expression c = super().resolve_expression(query, allow_joins, reuse, summarize) File "/.../django/db/models/expressions.py", line 300, in resolve_expression expr.resolve_expression(query, allow_joins, reuse, summarize) ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/.../django/db/models/expressions.py", line 300, in resolve_expression expr.resolve_expression(query, allow_joins, reuse, summarize) ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/.../django/db/models/expressions.py", line 941, in resolve_expression col = super().resolve_expression(*args, **kwargs) File "/.../django/db/models/expressions.py", line 902, in resolve_expression return query.resolve_ref(self.name, allow_joins, reuse, summarize) ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/.../django/db/models/sql/query.py", line 2049, in resolve_ref join_info = self.setup_joins( field_list, self.get_meta(), self.get_initial_alias(), can_reuse=reuse ) File "/.../django/db/models/sql/query.py", line 1900, in setup_joins path, final_field, targets, rest = self.names_to_path( ~~~~~~~~~~~~~~~~~~^ names[:pivot], ^^^^^^^^^^^^^^ ...<2 lines>... fail_on_missing=True, ^^^^^^^^^^^^^^^^^^^^^ ) ^ File "/.../django/db/models/sql/query.py", line 1805, in names_to_path raise FieldError( ...<2 lines>... ) django.core.exceptions.FieldError: Cannot resolve keyword 'position' into field. Choices are: book, book_id, id }}} This error again bisects to e306687a3a5507d59365ba9bf545010e5fd4b2a8. The cause is similar: duplicate `OuterRef` resolution occurs due to a clause left in `OrderableAggMixin.resolve_expression()`. -- -- Ticket URL: <https://code.djangoproject.com/ticket/36405#comment:3> 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 django-updates+unsubscr...@googlegroups.com. To view this discussion visit https://groups.google.com/d/msgid/django-updates/01070196f7a816e5-395d1037-7437-40bb-a285-8f8bc63050d7-000000%40eu-central-1.amazonses.com.