#35025 closed Bug (duplicate)

Crash when attempting to order by array index from annotated ArrayAgg

Reported by: Ben Nace Owned by: nobody
Component: Database layer (models, ORM) Version: 5.0
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Example models:

class ModelA(models.Model):
    name = models.CharField(max_length=100)


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

And with the following instances:

modelA = ModelA.objects.create(name='Test')
ModelB.objects.bulk_create([ModelB(model_a=modelA, value=1), ModelB(model_a=modelA, value=2)])

The following query results in AttributeError: 'ArrayField' object has no attribute 'model'

ModelA.objects.values('name').annotate(values=ArrayAgg('modelb__value')).order_by('values__0')

This crash also happens at least as far back as Django 4.2

Change History (4)

comment:1 by Simon Charette, 13 months ago

Could you provide the full traceback, it might be easier to diagnose and reproduce.

comment:2 by Ben Nace, 13 months ago

Full traceback:

Traceback (most recent call last):
  File "/home/bnace/python-envs/pmcs-50/lib/python3.11/site-packages/django/contrib/postgres/fields/array.py", line 44, in model
    return self.__dict__["model"]
           ~~~~~~~~~~~~~^^^^^^^^^
KeyError: 'model'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/home/bnace/python-envs/pmcs-50/lib/python3.11/site-packages/django/db/models/query.py", line 374, in __repr__
    data = list(self[: REPR_OUTPUT_SIZE + 1])
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/bnace/python-envs/pmcs-50/lib/python3.11/site-packages/django/db/models/query.py", line 398, in __iter__
    self._fetch_all()
  File "/home/bnace/python-envs/pmcs-50/lib/python3.11/site-packages/django/db/models/query.py", line 1926, in _fetch_all
    self._result_cache = list(self._iterable_class(self))
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/bnace/python-envs/pmcs-50/lib/python3.11/site-packages/django/db/models/query.py", line 208, in __iter__
    for row in compiler.results_iter(
               ^^^^^^^^^^^^^^^^^^^^^^
  File "/home/bnace/python-envs/pmcs-50/lib/python3.11/site-packages/django/db/models/sql/compiler.py", line 1513, in results_iter
    results = self.execute_sql(
              ^^^^^^^^^^^^^^^^^
  File "/home/bnace/python-envs/pmcs-50/lib/python3.11/site-packages/django/db/models/sql/compiler.py", line 1549, in execute_sql
    sql, params = self.as_sql()
                  ^^^^^^^^^^^^^
  File "/home/bnace/python-envs/pmcs-50/lib/python3.11/site-packages/django/db/models/sql/compiler.py", line 736, in as_sql
    extra_select, order_by, group_by = self.pre_sql_setup(
                                       ^^^^^^^^^^^^^^^^^^^
  File "/home/bnace/python-envs/pmcs-50/lib/python3.11/site-packages/django/db/models/sql/compiler.py", line 85, in pre_sql_setup
    order_by = self.get_order_by()
               ^^^^^^^^^^^^^^^^^^^
  File "/home/bnace/python-envs/pmcs-50/lib/python3.11/site-packages/django/db/models/sql/compiler.py", line 459, in get_order_by
    for expr, is_ref in self._order_by_pairs():
  File "/home/bnace/python-envs/pmcs-50/lib/python3.11/site-packages/django/db/models/sql/compiler.py", line 442, in _order_by_pairs
    yield from self.find_ordering_name(
               ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/bnace/python-envs/pmcs-50/lib/python3.11/site-packages/django/db/models/sql/compiler.py", line 1086, in find_ordering_name
    return [
           ^
  File "/home/bnace/python-envs/pmcs-50/lib/python3.11/site-packages/django/db/models/sql/compiler.py", line 1087, in <listcomp>
    (OrderBy(transform_function(t, alias), descending=descending), False)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/bnace/python-envs/pmcs-50/lib/python3.11/site-packages/django/db/models/sql/query.py", line 1876, in transform
    wrapped = previous(field, alias)
              ^^^^^^^^^^^^^^^^^^^^^^
  File "/home/bnace/python-envs/pmcs-50/lib/python3.11/site-packages/django/db/models/sql/query.py", line 1847, in final_transformer
    return field.get_col(alias)
           ^^^^^^^^^^^^^^^^^^^^
  File "/home/bnace/python-envs/pmcs-50/lib/python3.11/site-packages/django/db/models/fields/__init__.py", line 542, in get_col
    if alias == self.model._meta.db_table and (
                ^^^^^^^^^^
  File "/home/bnace/python-envs/pmcs-50/lib/python3.11/site-packages/django/contrib/postgres/fields/array.py", line 46, in model
    raise AttributeError(
AttributeError: 'ArrayField' object has no attribute 'model'

comment:3 by Simon Charette, 13 months ago

I think it's the ArrayField variant of the same problem faced with JSONField, see #34013.

comment:4 by Mariusz Felisiak, 13 months ago

Component: UncategorizedDatabase layer (models, ORM)
Resolution: duplicate
Status: newclosed
Type: UncategorizedBug

Good catch! Let's close it as a duplicate of #34013. If there is a solution, it will be the same for both.

Note: See TracTickets for help on using tickets.
Back to Top