﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
2453	"[patch] Define order in which ""initial sql data"" files are processed"	Pawel J. Sawicki (http://pjs.name)	nobody	"Since, according to http://www.djangoproject.com/documentation/model_api/#providing-initial-sql-data, there was no way to ensure an order in which multiple ""initial sql data"" files were processed during e.g. ""manage.py syncdb"" I've prepared the following patch. I hope it may be useful.

{{{

$ svn diff

Index: db/models/options.py
===================================================================
--- db/models/options.py	(revision 3496)
+++ db/models/options.py	(working copy)
@@ -13,7 +13,7 @@
 
 DEFAULT_NAMES = ('verbose_name', 'db_table', 'ordering',
                  'unique_together', 'permissions', 'get_latest_by',
-                 'order_with_respect_to', 'app_label')
+                 'order_with_respect_to', 'app_label', 'sql_initialization_order')
 
 class Options(object):
     def __init__(self, meta):
@@ -41,6 +41,7 @@
         self.object_name = cls.__name__
         self.module_name = self.object_name.lower()
         self.verbose_name = get_verbose_name(self.object_name)
+        self.sql_initialization_order = 0
         # Next, apply any overridden values from 'class Meta'.
         if self.meta:
             meta_attrs = self.meta.__dict__
Index: core/management.py
===================================================================
--- core/management.py	(revision 3496)
+++ core/management.py	(working copy)
@@ -492,21 +492,40 @@
 
         # Install initial data for the app (but only if this is a model we've
         # just created)
+        sql_initial_data = {}
         for model in models.get_models(app):
             if model in created_models:
                 initial_sql = get_sql_initial_data_for_model(model)
                 if initial_sql:
-                    print ""Installing initial data for %s model"" % model._meta.object_name
+                    # Get the order in which the model should be initialized.
+                    sql_initialization_order = model._meta.sql_initialization_order
                     try:
-                        for sql in initial_sql:
-                            cursor.execute(sql)
-                    except Exception, e:
-                        sys.stderr.write(""Failed to install initial SQL data for %s model: %s"" % \
-                                            (model._meta.object_name, e))
-                        transaction.rollback_unless_managed()
-                    else:
-                        transaction.commit_unless_managed()
+                        sql_initial_data[sql_initialization_order].append(model)
+                    except KeyError:
+                        sql_initial_data[sql_initialization_order] = [model, ]
 
+        # Once we have the initial sql data together with its respective
+        # weights try to install it in an appropriate order.
+        sql_initial_data_keys = sql_initial_data.keys()
+        sql_initial_data_keys.sort()
+        for sql_initialization_order in sql_initial_data_keys:
+            while len(sql_initial_data[sql_initialization_order]):
+                model = sql_initial_data[sql_initialization_order].pop()
+                
+                print ""Installing initial data for %s model"" % model._meta.object_name
+
+                initial_sql = get_sql_initial_data_for_model(model)
+
+                try:
+                    for sql in initial_sql:
+                        cursor.execute(sql)
+                except Exception, e:
+                    sys.stderr.write(""Failed to install initial SQL data for %s model: %s"" % \
+                                        (model._meta.object_name, e))
+                    transaction.rollback_unless_managed()
+                else:
+                    transaction.commit_unless_managed()
+
 syncdb.args = ''
 
 def get_admin_index(app):

}}}

If you want to influence the order in which files with initial sql data are processed you have to place an attribute called ""sql_initialization_order"" inside the ""Meta"" class of a specific model class. The smaller the number, the earlier the file associated with this model will be processed.

This way, if you have multiple models that depend one on another, you may use separate sql initialization files, without the risk of breaking constraints."	enhancement	closed	Core (Other)	dev	minor	wontfix		sam@…	Design decision needed	1	0	0	0	0	0
