Opened 14 years ago
Closed 9 years ago
#14096 closed Bug (invalid)
Insert code generated by models using multiple inheritance is incorrect and fails in postgresql
Reported by: | Arthur Pemberton | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 1.2 |
Severity: | Normal | Keywords: | orm |
Cc: | Triage Stage: | Accepted | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | yes | Patch needs improvement: | yes |
Easy pickings: | no | UI/UX: | no |
Description
When a model with multiple concrete parents is saved (inserted) the parents are saved first. Currently, the first parent is saved and its primary key is also set as the primary key of the yet unsaved top model. Any parent following uses the new primary key of 'self' and explicitly inserts the PK into the parent models table
There is no reason to explicitly set the PK of any of the parent classes, the code already handles retrieval of the DB assigned PK.
While other DBs let this pass, PostgreSQL does not. The problem comes not on the offending .save() but subsequent inserts to the table, this time without an explicit PK. The DB's internal counter has not advanced, so the next chosen PK already exists and yields a database error due to duplicate of a key field.
There is no apparent need to explicitly set any of the PK on insert. I believe that changing the following code block within source:django/trunk/django/db/models/base.py#13538 , line 533 , Model.save_base(...) can solve the problem:
from
if update_pk: setattr(self, meta.pk.attname, result)
to
if update_pk and cls == self.__class__: setattr(self, meta.pk.attname, result)
I have attached a sample site ('minherit') with app ('data') and a test case in a ZIP file.
Attachments (3)
Change History (15)
by , 14 years ago
Attachment: | minherit.zip added |
---|
comment:1 by , 14 years ago
Has patch: | set |
---|
comment:2 by , 14 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
comment:3 by , 14 years ago
Resolution: | fixed |
---|---|
Status: | closed → reopened |
comment:4 by , 14 years ago
Needs tests: | set |
---|---|
Patch needs improvement: | set |
Triage Stage: | Unreviewed → Accepted |
comment:5 by , 13 years ago
Severity: | → Normal |
---|---|
Type: | → Bug |
comment:8 by , 12 years ago
Status: | reopened → new |
---|
comment:9 by , 10 years ago
I'm experiencing the same issue here. Annoying. Any chance to see this fixed?
comment:11 by , 10 years ago
Well, I've made a workaround with Postgres by having the model tables rely on the same SEQUENCE counter:
ALTER TABLE mymodule_a ALTER COLUMN id SET DEFAULT nextval('mymodule_c_id_seq');
I'll dig further into this issue whenever I have more time.
comment:12 by , 9 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
Closing as invalid given the provided models don't validate:
data.Company: (models.E005) The field 'id' from parent model 'data.account' clashes with the field 'id' from parent model 'data.contact'. data.Employee.company: (models.E006) The field 'company' clashes with the field 'company' from model 'data.contact'.
same site with test case