#20002: Model inheritance depth may result in invalid SQL queries
----------------------------------------------+--------------------
Reporter: Keryn Knight <django@…> | Owner: nobody
Type: Bug | Status: new
Component: Database layer (models, ORM) | Version: 1.4
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
----------------------------------------------+--------------------
This is an example pulled out of the test case I was writing as a baseline
for something kind of crazy, and on '''1.4''' to boot.
Using
{{{
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': None,
}
}
}}}
for settings (to get an in-memory database for tests), and the following
models:
{{{
class A(Model):
subcontent_type = models.ForeignKey(ContentType, null=True,
related_name='+',
editable=False)
objects = Manager()
def __unicode__(self):
return unicode(self.pk)
class Meta:
ordering = ('pk',)
class B(A): pass
class C(B): pass
class D(C): pass
}}}
The following test case fails at evaluating D:
{{{
from django.test import TestCase as DjangoTestCase
class PolymorphTestCase(DjangoTestCase):
def setUp(self):
self.objects = [A.objects.create(), B.objects.create(),
C.objects.create(), D.objects.create(),
C.objects.create(), B.objects.create()]
def test_default_manager(self):
with self.assertNumQueries(4):
all = list(A.objects.all())
self.assertEqual(all, [
A(pk=1), A(pk=2), A(pk=3), A(pk=4), A(pk=5), A(pk=6),
])
all = list(B.objects.all())
self.assertEqual(all, [
B(pk=2), B(pk=3), B(pk=4), B(pk=5), B(pk=6),
])
all = list(C.objects.all())
self.assertEqual(all, [C(pk=3), C(pk=4), C(pk=5)])
import pdb; pdb.set_trace()
all = list(D.objects.all())
self.assertEqual(all, [D(pk=4)])
}}}
The stack trace is:
{{{
Traceback (most recent call last):
File "/path/to/tests.py", line 411, in test_default_manager
all = list(D.objects.all())
File "/path/python2.7/site-
packages/Django-1.4.5-py2.7.egg/django/db/models/query.py", line 87, in
__len__
self._result_cache.extend(self._iter)
File "/path/python2.7/site-
packages/Django-1.4.5-py2.7.egg/django/db/models/query.py", line 291, in
iterator
for row in compiler.results_iter():
File "/path/python2.7/site-
packages/Django-1.4.5-py2.7.egg/django/db/models/sql/compiler.py", line
763, in results_iter
for rows in self.execute_sql(MULTI):
File "/path/python2.7/site-
packages/Django-1.4.5-py2.7.egg/django/db/models/sql/compiler.py", line
818, in execute_sql
cursor.execute(sql, params)
File "/path/python2.7/site-
packages/Django-1.4.5-py2.7.egg/django/db/backends/util.py", line 40, in
execute
return self.cursor.execute(sql, params)
File "/path/python2.7/site-
packages/Django-1.4.5-py2.7.egg/django/db/backends/sqlite3/base.py", line
344, in execute
return Database.Cursor.execute(self, query, params)
DatabaseError: no such column: T5.a_ptr_id
}}}
the query used for D.objects.all() is:
{{{
'SELECT "testmodel_a"."id", "testmodel_a"."subcontent_type_id",
"testmodel_b"."a_ptr_id", "testmodel_c"."b_ptr_id",
"testmodel_d"."c_ptr_id" FROM "testmodel_d" INNER JOIN "testmodel_a" ON
("testmodel_d"."c_ptr_id" = "testmodel_a"."id") INNER JOIN "testmodel_b"
ON ("testmodel_d"."c_ptr_id" = "testmodel_b"."a_ptr_id") INNER JOIN
"testmodel_c" ON ("testmodel_d"."c_ptr_id" = "testmodel_c"."b_ptr_id")
INNER JOIN "testmodel_a" T6 ON (T5."a_ptr_id" = T6."id") ORDER BY
"testmodel_d"."c_ptr_id" ASC'
}}}
I had a look at the model_inheritance tests, and couldn't see any that
were testing to the depth I'm doing there, so either I'm doing something
wrong, SQlite is (as always) being a pain, or the tests may not go far
enough.
--
Ticket URL: <https://code.djangoproject.com/ticket/20002>
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 post to this group, send email to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.