#1928 closed defect (fixed)
[patch] Forget some foreignkeys during "python manage.py syncdb" with an empty postgres db.
Reported by: | hornero | Owned by: | Adrian Holovaty |
---|---|---|---|
Component: | Core (Management commands) | Version: | dev |
Severity: | major | Keywords: | Forget foreignkey django-admin.py |
Cc: | landonf@… | Triage Stage: | Unreviewed |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
For models with several foreignkeys to the same table, like this :
class File(models.Model): Name = models.CharField(maxlength=200,null=False, blank=False, unique=True) Storage = models.CharField(maxlength=200, null=True, blank=True) def __repr__(self): return self.Name
class Job(models.Model): Name = models.CharField(maxlength=200) Script_FK = models.ForeignKey(File,related_name='Script', verbose_name="The script file",null=True, blank=True) JobLog_FK = models.ForeignKey(File,related_name='JobLog', verbose_name="The log file",null=True, blank=True) def __repr__(self): return self.Name
class Header(models.Model): FULL_PATH_FITS = models.CharField(maxlength=200, null=False, blank=False, unique=True) Fits_File_FK = models.ForeignKey(File, related_name='Fits_File_FK', verbose_name="The related File",null=True, blank=True) def __repr__(self): return str(int(self.FULL_PATH_FITS))
When we launch python manage.py syncdb" with an empty postgres db, some foreignkeys are missing :
=> \d process_job Table "public.process_job" Column | Type | Modifiers --------------+------------------------+---------------------------------------------------------- id | integer | not null default nextval('process_job_id_seq'::regclass) Name | character varying(200) | not null Script_FK_id | integer | JobLog_FK_id | integer | Indexes: "process_job_pkey" PRIMARY KEY, btree (id) Foreign-key constraints: "JobLog_FK_id_referencing_process_file_id" FOREIGN KEY ("JobLog_FK_id") REFERENCES process_file(id) "Script_FK_id_referencing_process_file_id" FOREIGN KEY ("Script_FK_id") REFERENCES process_file(id) => \d process_header Table "public.process_header" Column | Type | Modifiers --------------------+------------------------+------------------------------------------------------------- id | integer | not null default nextval('process_header_id_seq'::regclass) FULL_PATH_FITS | character varying(200) | not null Fits_File_FK_id | integer | Indexes: "process_header_pkey" PRIMARY KEY, btree (id) "process_header_FULL_PATH_FITS_key" UNIQUE, btree ("FULL_PATH_FITS")
I think the problem start with the update of the dictionnary "pending_references" in django/core/management.py :
(In the function syncdb()):
449 sql, references = _get_sql_model_create(model, seen_models) 450 seen_models.add(model) 451 created_models.add(model) 452 pending_references.update(references) #===============> Problem... 453 sql.extend(_get_sql_for_pending_references(model, pending_references))
The update function overwrites the previous references to the file table with the new ones.
In order to keep the previous foreignkeys, I've written the folowing function to replace the update dictionnary function :
def update_dict(dict_input = {},dict_update = {}): "New update function which keep the previous references." dict_output = dict_input try : for k_update, v_update in dict_update.items() : try : value_to_update = dict_input[k_update] value_output = value_to_update + v_update dict_output[k_update] = value_output except : dict_output[k_update] = v_update except : dict_output.update(dict_update) return dict_output
and call it in syncdb():
pending_references = update_dict(pending_references,references)
The same error can be found in get_sql_create(app).
Now, in the db, we have :
\d process_header Table "public.process_header" Column | Type | Modifiers --------------------+------------------------+------------------------------------------------------------- id | integer | not null default nextval('process_header_id_seq'::regclass) FULL_PATH_FITS | character varying(200) | not null Fits_File_FK_id | integer | Indexes: "process_header_pkey" PRIMARY KEY, btree (id) "process_header_FULL_PATH_FITS_key" UNIQUE, btree ("FULL_PATH_FITS") Foreign-key constraints: "Fits_File_FK_id_referencing_process_file_id" FOREIGN KEY ("Fits_File_FK_id") REFERENCES process_file(id) \d process_job Table "public.process_job" Column | Type | Modifiers --------------+------------------------+---------------------------------------------------------- id | integer | not null default nextval('process_job_id_seq'::regclass) Name | character varying(200) | not null Script_FK_id | integer | JobLog_FK_id | integer | Indexes: "process_job_pkey" PRIMARY KEY, btree (id) Foreign-key constraints: "JobLog_FK_id_referencing_process_file_id" FOREIGN KEY ("JobLog_FK_id") REFERENCES process_file(id) "Script_FK_id_referencing_process_file_id" FOREIGN KEY ("Script_FK_id") REFERENCES process_file(id)
Attachments (1)
Change History (5)
comment:1 by , 18 years ago
by , 18 years ago
Attachment: | bug1928.diff added |
---|
Based on Shaun's solution mentioned in the forum thread.
comment:2 by , 18 years ago
Summary: | Forget some foreignkeys during "python manage.py syncdb" with an empty postgres db. → [patch] Forget some foreignkeys during "python manage.py syncdb" with an empty postgres db. |
---|
Adding a patch based on Shaun's solution mentioned in the forum thread (see in the Change History of this bug report).
Just had to make it work, so I figured I upload a patch.
comment:3 by , 18 years ago
Cc: | added |
---|
comment:4 by , 18 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
See also http://groups.google.com/group/django-developers/browse_thread/thread/8759bfc01f5fcce7/aa6790e5a58a0766 where the cause is diagnosed and a solution proposed.