#19073: strange behaviour of select_related
-------------------------------------+-------------------------------------
Reporter: anonymous | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version: 1.4
(models, ORM) | Resolution:
Severity: Normal | Triage Stage:
Keywords: | Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by anonymous):
* status: closed => new
* resolution: worksforme =>
Comment:
With the model defined above, the following test fails (django 1.4):
{{{#!python
def test_bug19073_ABCD(self):
nb_of_objects = 10
{D.objects.create() for _i in xrange(nb_of_objects)}
self.assertEqual(len(D.objects.all()), nb_of_objects) # ok
self.assertEqual(len(D.objects.select_related('b').all()),
nb_of_objects) # ok
self.assertEqual(len(D.objects.select_related('b__c').all()),
nb_of_objects) # ok
self.assertEqual(len(D.objects.select_related('b__c__a').all()),
nb_of_objects) # nok
self.assertEqual(len(D.objects.select_related('b__c__b').all()),
nb_of_objects) # nok
}}}
A similar problem is with the following model (OneToOneField 'hidden' in
the inheritance):
{{{#!python
class R(models.Model):
pass
class P(models.Model):
pass
class Q(P):
r = models.ForeignKey(R)
pass
class O(models.Model):
p = models.ForeignKey(P, null=True)
}}}
and with the following test:
{{{#!python
def test_bug19073_OPQR(self):
nb_of_objects = 10
{O.objects.create() for _i in xrange(nb_of_objects)}
self.assertEqual(len(O.objects.all()), nb_of_objects) # ok
self.assertEqual(len(O.objects.select_related('p').all()),
nb_of_objects) # ok
self.assertEqual(len(O.objects.select_related('p__q').all()),
nb_of_objects) # ok
self.assertEqual(len(O.objects.select_related('p__q__r').all()),
nb_of_objects) # nok
}}}
In every "nok" cases, there is a INNER JOIN in the underlying query that
messes things up.
Strangely enough, note that the following "simpler" model J->K->L->M (no
inheritance as opposed to O->P=>Q->R and without going reverse C->B as in
D->B, C->{B,A} above), works:
{{{#!python
class M(models.Model): #rush
pass
class L(models.Model): #captured_snapshot
m = models.ForeignKey(M)
pass
class K(models.Model): #snapshot
l = models.OneToOneField(L)
pass
class J(models.Model): #talk
k = models.OneToOneField(K, null=True)
}}}
Tests are all ok here:
{{{#!python
def test_bug19073_JKLM(self):
nb_of_objects = 10
{J.objects.create() for _i in xrange(nb_of_objects)}
self.assertEqual(len(J.objects.all()), nb_of_objects) # ok
self.assertEqual(len(J.objects.select_related('k').all()),
nb_of_objects) # ok
self.assertEqual(len(J.objects.select_related('k__l').all()),
nb_of_objects) # ok
self.assertEqual(len(J.objects.select_related('k__l__m').all()),
nb_of_objects) # ok <- strange!
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/19073#comment:2>
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 post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit https://groups.google.com/groups/opt_out.