Opened 11 years ago

Closed 11 years ago

Last modified 11 years ago

#10251 closed (fixed)

Problem with inheritance plus explicit primary_key in child model

Reported by: Karen Tracey Owned by: Malcolm Tredinnick
Component: Database layer (models, ORM) Version: 1.0
Severity: Keywords:
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


Given these models:

class BaseM(models.Model):
  base_name = models.CharField(max_length=100)
  def __unicode__(self):
    return self.base_name

class DerivedM(BaseM):
  customPK = models.IntegerField(primary_key=True)
  derived_name = models.CharField(max_length=100)
  def __unicode__(self):
    return "PK = %d, base_name = %s, derived_name = %s" % \
        (self.customPK, self.base_name, self.derived_name) 

The ORM can't seem to properly link parent with child models (reformatted for readability):

Python 2.5.1 (r251:54863, Jul 31 2008, 23:17:40)
[GCC 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from ttt.models import DerivedM
>>> from django.db import connection
>>> DerivedM.objects.create(customPK=44, base_name="b1", derived_name="d1")

<DerivedM: PK = 44, base_name = b1, derived_name = d1>
>>> DerivedM.objects.all()
>>> connection.queries[-1]

{'time': '0.006',
'sql': u'SELECT
       FROM `ttt_derivedm` INNER JOIN `ttt_basem`
       ON (`ttt_derivedm`.`customPK` = `ttt_basem`.`id`) LIMIT 21'}

This was originally tracked down in this thread but the OP doesn't seem interested in pursuing:

Seems to me either an error should be reported on trying to override primary_key in the child model, or the parent-child link should work.

Change History (7)

comment:1 Changed 11 years ago by Malcolm Tredinnick

Triage Stage: UnreviewedAccepted

I wouldn't cry if we made this an error.

However, since multi-inheritance is permitted, it's clearly not a requirement of the internals that all relations to parent models are primary keys. So maybe we can accommodate this.

comment:2 Changed 11 years ago by Alex Gaynor

I'm of the opinion that the value in supporting this is severely out weighed by the value in not supporting it, specifically if we don't support it we can do nifty optimizations like what I posted in #9394 all the time. As best I can tell the only point of supporting this would essentially be for the model to have 2 primary keys(2 not null unique fields) you can still keep the extra field, put an index on it, whatever, but giving it the primary key semantic is more trouble than it's worth.

comment:3 Changed 11 years ago by Malcolm Tredinnick

You can't have two primary keys on a database table (by definition). However, we already support non-primary-key links to parent models (due to supporting multiple inheritance), so that's why this probably should just work. It's just an oversight in an edge-case and should be relatively simple to fix. This isn't the place to advocate for the "nifty optimisation" in the other ticket. That's independent of this.

comment:4 Changed 11 years ago by Alex Gaynor

I'm not advocating the optimization here(well I suppose I am, but it's incidental) the point is optimizations of that nature are easier to do if this is disallowed, because otherwise we have to trace the entire chain of pks and find if any of them aren't actually the parent link.

comment:5 Changed 11 years ago by Malcolm Tredinnick

Owner: changed from nobody to Malcolm Tredinnick

comment:6 Changed 11 years ago by Malcolm Tredinnick

Resolution: fixed
Status: newclosed

(In [9970]) Fixed #10251 -- Fixed model inheritance when there's also an explicit pk field.

comment:7 Changed 11 years ago by Malcolm Tredinnick

(In [9972]) [1.0.X] Fixed #10251 -- Fixed model inheritance when there's also an explicit pk field.

Backport of r9970 from trunk.

Note: See TracTickets for help on using tickets.
Back to Top