Django

Code

Ticket #1928 (closed: fixed)

Opened 3 years ago

Last modified 2 years ago

[patch] Forget some foreignkeys during "python manage.py syncdb" with an empty postgres db.

Reported by: hornero Assigned to: adrian
Milestone: Component: django-admin.py
Version: SVN Keywords: Forget foreignkey django-admin.py
Cc: landonf@opendarwin.org Triage Stage: Unreviewed
Has patch: 1 Needs documentation: 0
Needs tests: 0 Patch needs improvement: 0

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

bug1928.diff (0.8 kB) - added by Geert Vanderkelen on 06/11/06 04:35:25.
Based on Shaun's solution mentioned in the forum thread.

Change History

05/20/06 20:04:54 changed by mtredinnick

06/11/06 04:35:25 changed by Geert Vanderkelen

  • attachment bug1928.diff added.

Based on Shaun's solution mentioned in the forum thread.

06/11/06 04:37:47 changed by Geert Vanderkelen

  • summary changed from Forget some foreignkeys during "python manage.py syncdb" with an empty postgres db. to [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.

06/19/06 13:28:59 changed by anonymous

  • cc set to landonf@opendarwin.org.

06/20/06 22:39:47 changed by mtredinnick

  • status changed from new to closed.
  • resolution set to fixed.

(In [3182]) Fixed #1928 -- Correctly create foreign key references when there are multiple keys on multiple models. Based on a patch from Geert Vanderkelen and some diagnosis from hornero.


Add/Change #1928 ([patch] Forget some foreignkeys during "python manage.py syncdb" with an empty postgres db.)




Change Properties
Action