#10406 closed (fixed)
Primary keys with model inheritance problems.
Reported by: | Ramiro Morales | Owned by: | Malcolm Tredinnick |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | Keywords: | parent_link primary_key onetoonefield | |
Cc: | Triage Stage: | Accepted | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
With this model setup:
from django.db import models class Persona(models.Model): nombre = models.CharField(max_length=60) class Cliente(Persona): cli_id = models.AutoField(primary_key=True) persona = models.OneToOneField(Persona, parent_link=True)
sqlall
output (with SQLite, MySQL shows the same) shows that the two Client fields are declared PRIMARY KEY
:
CREATE TABLE "thread1_persona" ( "id" integer NOT NULL PRIMARY KEY, "nombre" varchar(60) NOT NULL ) ; CREATE TABLE "thread1_cliente" ( "cli_id" integer NOT NULL PRIMARY KEY, "persona_id" integer NOT NULL PRIMARY KEY REFERENCES "thread1_persona" ("id") ) ; COMMIT;
Problem also show if the explicit Cliente PK is changed from AutoField to another field type.
Commenting out http://code.djangoproject.com/browser/django/trunk/django/db/models/base.py#L101
solves the problem (and Django test suite still passes):
BEGIN; CREATE TABLE "thread1_persona" ( "id" integer NOT NULL PRIMARY KEY, "nombre" varchar(60) NOT NULL ) ; CREATE TABLE "thread1_cliente" ( "cli_id" integer NOT NULL PRIMARY KEY, "persona_id" integer NOT NULL UNIQUE REFERENCES "thread1_persona" ("id") ) ; COMMIT;
If Cliente is changed to inherit from models.Model, problem also goes away.
This issue could be related to #10251, but the example posted there doesn't show this double PK problem because it isn't using an explicit OneToOneField with parent_link for the inheritance.
Change History (6)
follow-up: 3 comment:1 by , 16 years ago
Owner: | changed from | to
---|
comment:2 by , 16 years ago
Triage Stage: | Unreviewed → Accepted |
---|
comment:3 by , 16 years ago
Summary: | Explicit PK plus explicit multi-table inheritance parent link o2o field result in two primary keys → Inconsistent handling of primary key flag between implicit and explicit (parent_link=True) model inheritance o2o fields when another explicit PK field is also used |
---|
Replying to mtredinnick:
It's the same sort of problem as #10251 (and a couple of others). I'm looking at those at the moment, so I suspect this will get fixed in passing.
Ok, here is a bit of additional info I was going to post, HTH:
Further tests show that the parent_link=True
part isn't even needed to reproduce this situation.
This would make this ticket a duplicate of #7367 but IMHO that ticket was both opened and closed because of the wrong reasons.
If a multi-table inheritance o2o field should be always a child model PK we have an inconsistency because if rather that using OneToOneField(Persona, parent_link=True)
we let Django handle the inheritance with its <whatever>_prt_id
implicit field it doesn't automatically flag it as a primary key:
class Cliente(Persona): cli_id = models.AutoField(primary_key=True)
-- ... CREATE TABLE "thread1_cliente" ( "persona_ptr_id" integer NOT NULL UNIQUE REFERENCES "thread1_persona" ("id"), "cli_id" integer NOT NULL PRIMARY KEY ) ;
I will re-purpose this ticket to be about this inconsistency.
Another problem possibly exposed by this example is the fact that model validation isn't catching the double PK condition. Will open a ticket depending on feedback about this one.
comment:4 by , 16 years ago
Summary: | Inconsistent handling of primary key flag between implicit and explicit (parent_link=True) model inheritance o2o fields when another explicit PK field is also used → Primary keys with model inheritance problems. |
---|
Relax. This doesn't need another ticket (and the paragraph-long title isn't really making things clearer at a glance. :-))
We're just messing up the pk assignment in some cases. It's the same root cause as #10251. #7367 is an old ticket (pre-queryset-refactor) and one-to-one fields no longer need to be primary keys, since otherwise multiple inheritance wouldn't be possible.
comment:5 by , 16 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
comment:6 by , 16 years ago
(In [9973]) [1.0.X] Fixed #10406 -- Fixed some problems with model inheritance and pk fields.
Manually specifying both a OneToOneField(parent_link=True) and separate a
primary key field was causing invalid SQL to be generated. Thanks to Ramiro
Morales for some analysis on this one.
Backport of r9971 from trunk.
It's the same sort of problem as #10251 (and a couple of others). I'm looking at those at the moment, so I suspect this will get fixed in passing.