#34229: "no such column" when combining FilteredRelation and multi-table
inheritance models
-------------------------------------+-------------------------------------
Reporter: lufte | Owner: nobody
Type: | Status: new
Uncategorized |
Component: Database | Version: 4.1
layer (models, ORM) | Keywords: filteredrelation
Severity: Normal | such column
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
I have found that a certain queryset that combines multi-table inheritance
models, FilteredRelation, and aggregation, can result in a "no such
column" database error.
The following `models.py` and `tests.py` modules can be placed in the app
of a newly created Django project to reproduce the bug. I've successfully
reproduced it with Django 3.2.4 (using PostgreSQL) and 4.1.4 (using
sqlite3). The tests module includes two tests which are pretty similar,
however one of them fails because of this bug, the full stacktrace being:
{{{
Traceback (most recent call last):
File "/tmp/env/lib/python3.10/site-
packages/django/db/backends/utils.py", line 89, in _execute
return self.cursor.execute(sql, params)
File "/tmp/env/lib/python3.10/site-
packages/django/db/backends/sqlite3/base.py", line 357, in execute
return Database.Cursor.execute(self, query, params)
sqlite3.OperationalError: no such column: myapp_user.superuser
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/tmp/dec1389/myapp/tests.py", line 34, in test_fails
print(
File "/tmp/env/lib/python3.10/site-packages/django/db/models/query.py",
line 370, in __repr__
data = list(self[: REPR_OUTPUT_SIZE + 1])
File "/tmp/env/lib/python3.10/site-packages/django/db/models/query.py",
line 394, in __iter__
self._fetch_all()
File "/tmp/env/lib/python3.10/site-packages/django/db/models/query.py",
line 1867, in _fetch_all
self._result_cache = list(self._iterable_class(self))
File "/tmp/env/lib/python3.10/site-packages/django/db/models/query.py",
line 87, in __iter__
results = compiler.execute_sql(
File "/tmp/env/lib/python3.10/site-
packages/django/db/models/sql/compiler.py", line 1398, in execute_sql
cursor.execute(sql, params)
File "/tmp/env/lib/python3.10/site-
packages/django/db/backends/utils.py", line 67, in execute
return self._execute_with_wrappers(
File "/tmp/env/lib/python3.10/site-
packages/django/db/backends/utils.py", line 80, in _execute_with_wrappers
return executor(sql, params, many, context)
File "/tmp/env/lib/python3.10/site-
packages/django/db/backends/utils.py", line 84, in _execute
with self.db.wrap_database_errors:
File "/tmp/env/lib/python3.10/site-packages/django/db/utils.py", line
91, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/tmp/env/lib/python3.10/site-
packages/django/db/backends/utils.py", line 89, in _execute
return self.cursor.execute(sql, params)
File "/tmp/env/lib/python3.10/site-
packages/django/db/backends/sqlite3/base.py", line 357, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.OperationalError: no such column: myapp_user.superuser
}}}
=== models.py:
{{{
from django.db import models
class School(models.Model):
name = models.CharField(max_length=100)
class User(models.Model):
superuser = models.BooleanField(default=True)
class Student(User):
superstudent = models.BooleanField(default=True)
school = models.ForeignKey(School, on_delete=models.CASCADE)
}}}
=== tests.py
{{{
from django.test import TestCase
from django.db.models import Q, FilteredRelation, Count
from .models import School, Student
class FilteredRelationBugTestCase(TestCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
p = School.objects.create(name='p1')
Student.objects.create(school=p, superuser=False,
superstudent=False)
Student.objects.create(school=p, superuser=False,
superstudent=True)
Student.objects.create(school=p, superuser=True,
superstudent=False)
Student.objects.create(school=p, superuser=True,
superstudent=True)
def test_works(self):
print(
School.objects.annotate(
superstudents=FilteredRelation(
'student',
condition=Q(
student__superstudent=True,
),
),
superuser_count=Count(
'superstudents',
filter=Q(superstudents__superuser=True)
),
).all()
)
def test_fails(self):
print(
School.objects.annotate(
superusers=FilteredRelation(
'student',
condition=Q(
student__superuser=True,
),
),
superstudents_count=Count(
'superusers',
filter=Q(superusers__superstudent=True)
),
).all()
)
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/34229>
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/010701855082f374-35537afc-9d6f-4402-8c7b-4610b975ae71-000000%40eu-central-1.amazonses.com.