#33282: django.db.utils.ProgrammingError: more than one row returned by a
subquery
used as an expression
-------------------------------------+-------------------------------------
Reporter: Antonio | Owner: nobody
Terceiro |
Type: Bug | Status: new
Component: Database | Version: 3.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 |
-------------------------------------+-------------------------------------
Hi,
I'm working on porting [https://lavasoftware.org lava] to Django 3.2. When
I run the test suite, I find 2 issues. One is #32690, for which I have the
corresponding patch backported locally. The other one is this is a bunch
of crashes that look like this:
E django.db.utils.ProgrammingError: more than one row
returned by a subquery used as an expression
I wasn't able to produce a minimal reproducer app yet, but I will try to
point to the relevant code.
in lava we have a few special model managers for handling access control.
They are here:
https://git.lavasoftware.org/lava/lava/-/blob/master/lava_scheduler_app/managers.py
This issue can easily be reproduced in a shell session:
{{{
$ ./manage.py shell
Python 3.9.8 (main, Nov 7 2021, 15:47:09)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.27.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: from lava_scheduler_app.models import TestJob, User
In [2]: TestJob.objects.visible_by_user(User.objects.last())
Out[2]:
---------------------------------------------------------------------------
CardinalityViolation Traceback (most recent call
last)
/usr/lib/python3/dist-packages/django/db/backends/utils.py in
_execute(self, sql, params, *ignored_wrapper_args)
83 else:
---> 84 return self.cursor.execute(sql, params)
85
CardinalityViolation: more than one row returned by a subquery used as an
expression
The above exception was the direct cause of the following exception:
ProgrammingError Traceback (most recent call
last)
/usr/lib/python3/dist-packages/IPython/core/formatters.py in
__call__(self, obj)
700 type_pprinters=self.type_printers,
701 deferred_pprinters=self.deferred_printers)
--> 702 printer.pretty(obj)
703 printer.flush()
704 return stream.getvalue()
/usr/lib/python3/dist-packages/IPython/lib/pretty.py in pretty(self, obj)
392 if cls is not object \
393 and
callable(cls.__dict__.get('__repr__')):
--> 394 return _repr_pprint(obj, self, cycle)
395
396 return _default_pprint(obj, self, cycle)
/usr/lib/python3/dist-packages/IPython/lib/pretty.py in _repr_pprint(obj,
p, cycle)
698 """A pprint that just redirects to the normal repr
function."""
699 # Find newlines and replace them with p.break_()
--> 700 output = repr(obj)
701 lines = output.splitlines()
702 with p.group():
/usr/lib/python3/dist-packages/django/db/models/query.py in __repr__(self)
254
255 def __repr__(self):
--> 256 data = list(self[:REPR_OUTPUT_SIZE + 1])
257 if len(data) > REPR_OUTPUT_SIZE:
258 data[-1] = "...(remaining elements truncated)..."
/usr/lib/python3/dist-packages/django/db/models/query.py in __len__(self)
260
261 def __len__(self):
--> 262 self._fetch_all()
263 return len(self._result_cache)
264
/usr/lib/python3/dist-packages/django/db/models/query.py in
_fetch_all(self)
1322 def _fetch_all(self):
1323 if self._result_cache is None:
-> 1324 self._result_cache = list(self._iterable_class(self))
1325 if self._prefetch_related_lookups and not
self._prefetch_done:
1326 self._prefetch_related_objects()
/usr/lib/python3/dist-packages/django/db/models/query.py in __iter__(self)
49 # Execute the query. This will also fill compiler.select,
klass_info,
50 # and annotations.
---> 51 results =
compiler.execute_sql(chunked_fetch=self.chunked_fetch,
chunk_size=self.chunk_size)
52 select, klass_info, annotation_col_map = (compiler.select,
compiler.klass_info,
53
compiler.annotation_col_map)
/usr/lib/python3/dist-packages/django/db/models/sql/compiler.py in
execute_sql(self, result_type, chunked_fetch, chunk_size)
1173 cursor = self.connection.cursor()
1174 try:
-> 1175 cursor.execute(sql, params)
1176 except Exception:
1177 # Might fail for server-side cursors (e.g. connection
closed)
/usr/lib/python3/dist-packages/django/db/backends/utils.py in
execute(self, sql, params)
96 def execute(self, sql, params=None):
97 with self.debug_sql(sql, params,
use_last_executed_query=True):
---> 98 return super().execute(sql, params)
99
100 def executemany(self, sql, param_list):
/usr/lib/python3/dist-packages/django/db/backends/utils.py in
execute(self, sql, params)
64
65 def execute(self, sql, params=None):
---> 66 return self._execute_with_wrappers(sql, params,
many=False, executor=self._execute)
67
68 def executemany(self, sql, param_list):
/usr/lib/python3/dist-packages/django/db/backends/utils.py in
_execute_with_wrappers(self, sql, params, many, executor)
73 for wrapper in reversed(self.db.execute_wrappers):
74 executor = functools.partial(wrapper, executor)
---> 75 return executor(sql, params, many, context)
76
77 def _execute(self, sql, params, *ignored_wrapper_args):
/usr/lib/python3/dist-packages/django/db/backends/utils.py in
_execute(self, sql, params, *ignored_wrapper_args)
82 return self.cursor.execute(sql)
83 else:
---> 84 return self.cursor.execute(sql, params)
85
86 def _executemany(self, sql, param_list,
*ignored_wrapper_args):
/usr/lib/python3/dist-packages/django/db/utils.py in __exit__(self,
exc_type, exc_value, traceback)
88 if dj_exc_type not in (DataError, IntegrityError):
89 self.wrapper.errors_occurred = True
---> 90 raise dj_exc_value.with_traceback(traceback) from
exc_value
91
92 def __call__(self, func):
/usr/lib/python3/dist-packages/django/db/backends/utils.py in
_execute(self, sql, params, *ignored_wrapper_args)
82 return self.cursor.execute(sql)
83 else:
---> 84 return self.cursor.execute(sql, params)
85
86 def _executemany(self, sql, param_list,
*ignored_wrapper_args):
ProgrammingError: more than one row returned by a subquery used as an
expression
}}}
If I downgrade Django to 2.2, that just works. This is reproducible with
Django 3.2 and with the current main branch from git.
--
Ticket URL: <https://code.djangoproject.com/ticket/33282>
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 view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/051.845a36dab3cf13f9aab6be8dde8a32d4%40djangoproject.com.