diff -r b758351d191f -r cc9b7e14412b web/lib/django/core/management/commands/syncdb.py --- a/web/lib/django/core/management/commands/syncdb.py Wed May 19 17:43:59 2010 +0200 +++ b/web/lib/django/core/management/commands/syncdb.py Tue May 25 02:43:45 2010 +0200 @@ -1,25 +1,26 @@ -from django.core.management.base import NoArgsCommand -from django.core.management.color import no_style -from django.utils.importlib import import_module from optparse import make_option import sys -try: - set -except NameError: - from sets import Set as set # Python 2.3 fallback +from django.conf import settings +from django.core.management.base import NoArgsCommand +from django.core.management.color import no_style +from django.core.management.sql import custom_sql_for_model, emit_post_sync_signal +from django.db import connections, router, transaction, models, DEFAULT_DB_ALIAS +from django.utils.datastructures import SortedDict +from django.utils.importlib import import_module + class Command(NoArgsCommand): option_list = NoArgsCommand.option_list + ( make_option('--noinput', action='store_false', dest='interactive', default=True, help='Tells Django to NOT prompt the user for input of any kind.'), + make_option('--database', action='store', dest='database', + default=DEFAULT_DB_ALIAS, help='Nominates a database to synchronize. ' + 'Defaults to the "default" database.'), ) help = "Create the database tables for all apps in INSTALLED_APPS whose tables haven't already been created." def handle_noargs(self, **options): - from django.db import connection, transaction, models - from django.conf import settings - from django.core.management.sql import custom_sql_for_model, emit_post_sync_signal verbosity = int(options.get('verbosity', 1)) interactive = options.get('interactive') @@ -46,6 +47,8 @@ if not msg.startswith('No module named') or 'management' not in msg: raise + db = options.get('database', DEFAULT_DB_ALIAS) + connection = connections[db] cursor = connection.cursor() # Get a list of already installed *models* so that references work right. @@ -54,16 +57,30 @@ created_models = set() pending_references = {} + # Build the manifest of apps and models that are to be synchronized + all_models = [ + (app.__name__.split('.')[-2], + [m for m in models.get_models(app, include_auto_created=True) + if router.allow_syncdb(db, m)]) + for app in models.get_apps() + ] + def model_installed(model): + opts = model._meta + converter = connection.introspection.table_name_converter + return not ((converter(opts.db_table) in tables) or + (opts.auto_created and converter(opts.auto_created._meta.db_table) in tables)) + + manifest = SortedDict( + (app_name, filter(model_installed, model_list)) + for app_name, model_list in all_models + ) + # Create the tables for each model - for app in models.get_apps(): - app_name = app.__name__.split('.')[-2] - model_list = models.get_models(app) + for app_name, model_list in manifest.items(): for model in model_list: # Create the model's database table, if it doesn't already exist. if verbosity >= 2: print "Processing %s.%s model" % (app_name, model._meta.object_name) - if connection.introspection.table_name_converter(model._meta.db_table) in tables: - continue sql, references = connection.creation.sql_create_model(model, self.style, seen_models) seen_models.add(model) created_models.add(model) @@ -78,36 +95,22 @@ cursor.execute(statement) tables.append(connection.introspection.table_name_converter(model._meta.db_table)) - # Create the m2m tables. This must be done after all tables have been created - # to ensure that all referred tables will exist. - for app in models.get_apps(): - app_name = app.__name__.split('.')[-2] - model_list = models.get_models(app) - for model in model_list: - if model in created_models: - sql = connection.creation.sql_for_many_to_many(model, self.style) - if sql: - if verbosity >= 2: - print "Creating many-to-many tables for %s.%s model" % (app_name, model._meta.object_name) - for statement in sql: - cursor.execute(statement) - transaction.commit_unless_managed() + transaction.commit_unless_managed(using=db) # Send the post_syncdb signal, so individual apps can do whatever they need # to do at this point. - emit_post_sync_signal(created_models, verbosity, interactive) + emit_post_sync_signal(created_models, verbosity, interactive, db) # The connection may have been closed by a syncdb handler. cursor = connection.cursor() # Install custom SQL for the app (but only if this # is a model we've just created) - for app in models.get_apps(): - app_name = app.__name__.split('.')[-2] - for model in models.get_models(app): + for app_name, model_list in manifest.items(): + for model in model_list: if model in created_models: - custom_sql = custom_sql_for_model(model, self.style) + custom_sql = custom_sql_for_model(model, self.style, connection) if custom_sql: if verbosity >= 1: print "Installing custom SQL for %s.%s model" % (app_name, model._meta.object_name) @@ -120,16 +123,16 @@ if show_traceback: import traceback traceback.print_exc() - transaction.rollback_unless_managed() + transaction.rollback_unless_managed(using=db) else: - transaction.commit_unless_managed() + transaction.commit_unless_managed(using=db) else: if verbosity >= 2: print "No custom SQL for %s.%s model" % (app_name, model._meta.object_name) + # Install SQL indicies for all newly created models - for app in models.get_apps(): - app_name = app.__name__.split('.')[-2] - for model in models.get_models(app): + for app_name, model_list in manifest.items(): + for model in model_list: if model in created_models: index_sql = connection.creation.sql_indexes_for_model(model, self.style) if index_sql: @@ -141,10 +144,9 @@ except Exception, e: sys.stderr.write("Failed to install index for %s.%s model: %s\n" % \ (app_name, model._meta.object_name, e)) - transaction.rollback_unless_managed() + transaction.rollback_unless_managed(using=db) else: - transaction.commit_unless_managed() + transaction.commit_unless_managed(using=db) - # Install the 'initial_data' fixture, using format discovery from django.core.management import call_command - call_command('loaddata', 'initial_data', verbosity=verbosity) + call_command('loaddata', 'initial_data', verbosity=verbosity, database=db)