#20776: Multi-level Multi-table Inheritance - mismatched PKs / explicit 
db_columns
-------------------------------+------------------------------------
     Reporter:  dowstreet@…    |      Owner:  nobody
         Type:  Bug            |     Status:  new
    Component:  Uncategorized  |    Version:  1.5
     Severity:  Normal         |   Keywords:  Muti-table Inheritance
 Triage Stage:  Unreviewed     |  Has patch:  0
Easy pickings:  0              |      UI/UX:  0
-------------------------------+------------------------------------
 There seems to be a problem with queries that (i) span several levels of
 multi-table inheritance subclassing when (ii) PKs do not match all the way
 up the hierarchy.  This situation can arise when a higher level object
 (e.g. parent) is created before a lower level object (e.g. grandchild).
 The query seems to use the PK of the grandchild's parent instead of
 walking the whole way up the hierarchy when looking up fields that are
 stored in the grandparent table.

 In the example below there are three levels in the class hierarchy.  When
 accessing the name field (which is stored in the Level1 base class) from
 an object in Level3, the query returns an unexpected value 'Top 1' instead
 of the expected 'Bot 1':

 {{{

 # models.py

 from django.db import models

 class Level1(models.Model):
  """ Top level base class """

  level1_id = models.AutoField(primary_key=True, db_column='Level1_ID')
  name = models.CharField(max_length=32, db_column='Name', blank=True,
 null=True)

  class Meta:
      db_table = 'Level1'


 class Level2(Level1):
  """ Middle level class """

  level2_id = models.AutoField(primary_key=True, db_column='Level2_ID')
  level1 = models.OneToOneField('Level1', db_column='Level1_ID',
 parent_link=True)  # parent class

  class Meta:
      db_table = 'Level2'


 class Level3(Level2):
  """ Bottom level class """

  level3_id = models.AutoField(primary_key=True, db_column='Level3_ID')
  level2 = models.OneToOneField('Level2', db_column='Level2_ID',
 parent_link=True)  # parent class

  class Meta:
      db_table = 'Level3'

 }}}

 Using the shell to add a Level1 object and then a Level3 object to an
 otherwise empty database:

 {{{

 from sc_test.models import *

 >>> top1 = Level1()
 >>> top1.name = 'Top 1'
 >>> top1.save()

 >>> bot1 = Level3()
 >>> bot1.name = 'Bot 1'
 >>> bot1.save()

 >>> l1 = Level1.objects.all()
 >>> l1
 [<Level1: Level1 object>, <Level1: Level1 object>]

 >>> l2 = Level2.objects.all()
 >>> l2
 [<Level2: Level2 object>]

 >>> l3 = Level3.objects.all()
 >>> l3
 [<Level3: Level3 object>]

 >>> l1[0].name
 u'Top 1'

 >>> l1[1].name
 u'Bot 1'

 >>> l2[0].name
 u'Bot 1'

 >>> l3[0].name
 u'Top 1'                               # WRONG!! - expected value is u'Bot
 1'

 }}}

 Note: In this example OneToOneField and ID/primary keys are manually added
 so that specific db_column names can be used.  It is unclear whether the
 problem is related to this combination, or whether it affects auto-
 generated OneToOneFields as well.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/20776>
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].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/064.a234389b2a0cca899ba197b4eb6ad0e9%40djangoproject.com.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to