Opened 8 years ago

Closed 8 years ago

Last modified 8 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: UI/UX:


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 8 years ago by Malcolm Tredinnick

Needs documentation: unset
Needs tests: unset
Patch needs improvement: unset
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 8 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 8 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 8 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 8 years ago by Malcolm Tredinnick

Owner: changed from nobody to Malcolm Tredinnick

comment:6 Changed 8 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 8 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