summaryrefslogtreecommitdiff
path: root/lib/python2.7/site-packages/south/management
diff options
context:
space:
mode:
authorttt2017-05-13 00:29:47 +0530
committerttt2017-05-13 00:29:47 +0530
commitabf599be33b383a6a5baf9493093b2126a622ac8 (patch)
tree4c5ab6e0d935d5e65fabcf0258e4a00dd20a5afa /lib/python2.7/site-packages/south/management
downloadSBHS-2018-Rpi-abf599be33b383a6a5baf9493093b2126a622ac8.tar.gz
SBHS-2018-Rpi-abf599be33b383a6a5baf9493093b2126a622ac8.tar.bz2
SBHS-2018-Rpi-abf599be33b383a6a5baf9493093b2126a622ac8.zip
added all server files
Diffstat (limited to 'lib/python2.7/site-packages/south/management')
-rw-r--r--lib/python2.7/site-packages/south/management/__init__.py0
-rw-r--r--lib/python2.7/site-packages/south/management/commands/__init__.py40
-rw-r--r--lib/python2.7/site-packages/south/management/commands/convert_to_south.py95
-rw-r--r--lib/python2.7/site-packages/south/management/commands/datamigration.py139
-rw-r--r--lib/python2.7/site-packages/south/management/commands/graphmigrations.py63
-rw-r--r--lib/python2.7/site-packages/south/management/commands/migrate.py264
-rw-r--r--lib/python2.7/site-packages/south/management/commands/migrationcheck.py67
-rw-r--r--lib/python2.7/site-packages/south/management/commands/schemamigration.py229
-rw-r--r--lib/python2.7/site-packages/south/management/commands/startmigration.py33
-rw-r--r--lib/python2.7/site-packages/south/management/commands/syncdb.py115
-rw-r--r--lib/python2.7/site-packages/south/management/commands/test.py8
-rw-r--r--lib/python2.7/site-packages/south/management/commands/testserver.py8
12 files changed, 1061 insertions, 0 deletions
diff --git a/lib/python2.7/site-packages/south/management/__init__.py b/lib/python2.7/site-packages/south/management/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/lib/python2.7/site-packages/south/management/__init__.py
diff --git a/lib/python2.7/site-packages/south/management/commands/__init__.py b/lib/python2.7/site-packages/south/management/commands/__init__.py
new file mode 100644
index 0000000..da218eb
--- /dev/null
+++ b/lib/python2.7/site-packages/south/management/commands/__init__.py
@@ -0,0 +1,40 @@
+
+# Common framework for syncdb actions
+
+import copy
+
+from django.core import management
+from django.conf import settings
+
+# Make sure the template loader cache is fixed _now_ (#448)
+import django.template.loaders.app_directories
+
+from south.hacks import hacks
+from south.management.commands.syncdb import Command as SyncCommand
+
+class MigrateAndSyncCommand(SyncCommand):
+ """Used for situations where "syncdb" is called by test frameworks."""
+
+ option_list = copy.deepcopy(SyncCommand.option_list)
+
+ for opt in option_list:
+ if "--migrate" == opt.get_opt_string():
+ opt.default = True
+ break
+
+def patch_for_test_db_setup():
+ # Load the commands cache
+ management.get_commands()
+ # Repoint to the correct version of syncdb
+ if hasattr(settings, "SOUTH_TESTS_MIGRATE") and not settings.SOUTH_TESTS_MIGRATE:
+ # point at the core syncdb command when creating tests
+ # tests should always be up to date with the most recent model structure
+ management._commands['syncdb'] = 'django.core'
+ else:
+ management._commands['syncdb'] = MigrateAndSyncCommand()
+ # Avoid flushing data migrations.
+ # http://code.djangoproject.com/ticket/14661 introduced change that flushed custom
+ # sql during the test database creation (thus flushing the data migrations).
+ # we patch flush to be no-op during create_test_db, but still allow flushing
+ # after each test for non-transactional backends.
+ hacks.patch_flush_during_test_db_creation()
diff --git a/lib/python2.7/site-packages/south/management/commands/convert_to_south.py b/lib/python2.7/site-packages/south/management/commands/convert_to_south.py
new file mode 100644
index 0000000..658ed48
--- /dev/null
+++ b/lib/python2.7/site-packages/south/management/commands/convert_to_south.py
@@ -0,0 +1,95 @@
+"""
+Quick conversion command module.
+"""
+
+from __future__ import print_function
+
+from optparse import make_option
+import sys
+
+from django.core.management.base import BaseCommand
+from django.core.management.color import no_style
+from django.conf import settings
+from django.db import models
+from django.core import management
+from django.core.exceptions import ImproperlyConfigured
+
+from south.migration import Migrations
+from south.hacks import hacks
+from south.exceptions import NoMigrations
+
+class Command(BaseCommand):
+
+ option_list = BaseCommand.option_list
+ if '--verbosity' not in [opt.get_opt_string() for opt in BaseCommand.option_list]:
+ option_list += (
+ make_option('--verbosity', action='store', dest='verbosity', default='1',
+ type='choice', choices=['0', '1', '2'],
+ help='Verbosity level; 0=minimal output, 1=normal output, 2=all output'),
+ )
+ option_list += (
+ make_option('--delete-ghost-migrations', action='store_true', dest='delete_ghosts', default=False,
+ help="Tells South to delete any 'ghost' migrations (ones in the database but not on disk)."),
+ make_option('--ignore-ghost-migrations', action='store_true', dest='ignore_ghosts', default=False,
+ help="Tells South to ignore any 'ghost' migrations (ones in the database but not on disk) and continue to apply new migrations."),
+ )
+
+ help = "Quickly converts the named application to use South if it is currently using syncdb."
+
+ def handle(self, app=None, *args, **options):
+
+ # Make sure we have an app
+ if not app:
+ print("Please specify an app to convert.")
+ return
+
+ # See if the app exists
+ app = app.split(".")[-1]
+ try:
+ app_module = models.get_app(app)
+ except ImproperlyConfigured:
+ print("There is no enabled application matching '%s'." % app)
+ return
+
+ # Try to get its list of models
+ model_list = models.get_models(app_module)
+ if not model_list:
+ print("This application has no models; this command is for applications that already have models syncdb'd.")
+ print("Make some models, and then use ./manage.py schemamigration %s --initial instead." % app)
+ return
+
+ # Ask South if it thinks it's already got migrations
+ try:
+ Migrations(app)
+ except NoMigrations:
+ pass
+ else:
+ print("This application is already managed by South.")
+ return
+
+ # Finally! It seems we've got a candidate, so do the two-command trick
+ verbosity = int(options.get('verbosity', 0))
+ management.call_command("schemamigration", app, initial=True, verbosity=verbosity)
+
+ # Now, we need to re-clean and sanitise appcache
+ hacks.clear_app_cache()
+ hacks.repopulate_app_cache()
+
+ # And also clear our cached Migration classes
+ Migrations._clear_cache()
+
+ # Now, migrate
+ management.call_command(
+ "migrate",
+ app,
+ "0001",
+ fake=True,
+ verbosity=verbosity,
+ ignore_ghosts=options.get("ignore_ghosts", False),
+ delete_ghosts=options.get("delete_ghosts", False),
+ )
+
+ print()
+ print("App '%s' converted. Note that South assumed the application's models matched the database" % app)
+ print("(i.e. you haven't changed it since last syncdb); if you have, you should delete the %s/migrations" % app)
+ print("directory, revert models.py so it matches the database, and try again.")
diff --git a/lib/python2.7/site-packages/south/management/commands/datamigration.py b/lib/python2.7/site-packages/south/management/commands/datamigration.py
new file mode 100644
index 0000000..c3175e7
--- /dev/null
+++ b/lib/python2.7/site-packages/south/management/commands/datamigration.py
@@ -0,0 +1,139 @@
+"""
+Data migration creation command
+"""
+
+from __future__ import print_function
+
+import sys
+import os
+import re
+from optparse import make_option
+
+try:
+ set
+except NameError:
+ from sets import Set as set
+
+from django.core.management.base import BaseCommand
+from django.core.management.color import no_style
+from django.db import models
+from django.conf import settings
+
+from south.migration import Migrations
+from south.exceptions import NoMigrations
+from south.creator import freezer
+
+class Command(BaseCommand):
+ option_list = BaseCommand.option_list + (
+ make_option('--freeze', action='append', dest='freeze_list', type='string',
+ help='Freeze the specified app(s). Provide an app name with each; use the option multiple times for multiple apps'),
+ make_option('--stdout', action='store_true', dest='stdout', default=False,
+ help='Print the migration to stdout instead of writing it to a file.'),
+ )
+ help = "Creates a new template data migration for the given app"
+ usage_str = "Usage: ./manage.py datamigration appname migrationname [--stdout] [--freeze appname]"
+
+ def handle(self, app=None, name="", freeze_list=None, stdout=False, verbosity=1, **options):
+
+ verbosity = int(verbosity)
+
+ # Any supposed lists that are None become empty lists
+ freeze_list = freeze_list or []
+
+ # --stdout means name = -
+ if stdout:
+ name = "-"
+
+ # Only allow valid names
+ if re.search('[^_\w]', name) and name != "-":
+ self.error("Migration names should contain only alphanumeric characters and underscores.")
+
+ # If not name, there's an error
+ if not name:
+ self.error("You must provide a name for this migration.\n" + self.usage_str)
+
+ if not app:
+ self.error("You must provide an app to create a migration for.\n" + self.usage_str)
+
+ # Ensure that verbosity is not a string (Python 3)
+ try:
+ verbosity = int(verbosity)
+ except ValueError:
+ self.error("Verbosity must be an number.\n" + self.usage_str)
+
+ # Get the Migrations for this app (creating the migrations dir if needed)
+ migrations = Migrations(app, force_creation=True, verbose_creation=verbosity > 0)
+
+ # See what filename is next in line. We assume they use numbers.
+ new_filename = migrations.next_filename(name)
+
+ # Work out which apps to freeze
+ apps_to_freeze = self.calc_frozen_apps(migrations, freeze_list)
+
+ # So, what's in this file, then?
+ file_contents = self.get_migration_template() % {
+ "frozen_models": freezer.freeze_apps_to_string(apps_to_freeze),
+ "complete_apps": apps_to_freeze and "complete_apps = [%s]" % (", ".join(map(repr, apps_to_freeze))) or ""
+ }
+
+ # - is a special name which means 'print to stdout'
+ if name == "-":
+ print(file_contents)
+ # Write the migration file if the name isn't -
+ else:
+ fp = open(os.path.join(migrations.migrations_dir(), new_filename), "w")
+ fp.write(file_contents)
+ fp.close()
+ print("Created %s." % new_filename, file=sys.stderr)
+
+ def calc_frozen_apps(self, migrations, freeze_list):
+ """
+ Works out, from the current app, settings, and the command line options,
+ which apps should be frozen.
+ """
+ apps_to_freeze = []
+ for to_freeze in freeze_list:
+ if "." in to_freeze:
+ self.error("You cannot freeze %r; you must provide an app label, like 'auth' or 'books'." % to_freeze)
+ # Make sure it's a real app
+ if not models.get_app(to_freeze):
+ self.error("You cannot freeze %r; it's not an installed app." % to_freeze)
+ # OK, it's fine
+ apps_to_freeze.append(to_freeze)
+ if getattr(settings, 'SOUTH_AUTO_FREEZE_APP', True):
+ apps_to_freeze.append(migrations.app_label())
+ return apps_to_freeze
+
+ def error(self, message, code=1):
+ """
+ Prints the error, and exits with the given code.
+ """
+ print(message, file=sys.stderr)
+ sys.exit(code)
+
+ def get_migration_template(self):
+ return MIGRATION_TEMPLATE
+
+
+MIGRATION_TEMPLATE = """# -*- coding: utf-8 -*-
+from south.utils import datetime_utils as datetime
+from south.db import db
+from south.v2 import DataMigration
+from django.db import models
+
+class Migration(DataMigration):
+
+ def forwards(self, orm):
+ "Write your forwards methods here."
+ # Note: Don't use "from appname.models import ModelName".
+ # Use orm.ModelName to refer to models in this application,
+ # and orm['appname.ModelName'] for models in other applications.
+
+ def backwards(self, orm):
+ "Write your backwards methods here."
+
+ models = %(frozen_models)s
+
+ %(complete_apps)s
+ symmetrical = True
+"""
diff --git a/lib/python2.7/site-packages/south/management/commands/graphmigrations.py b/lib/python2.7/site-packages/south/management/commands/graphmigrations.py
new file mode 100644
index 0000000..6ff1e47
--- /dev/null
+++ b/lib/python2.7/site-packages/south/management/commands/graphmigrations.py
@@ -0,0 +1,63 @@
+"""
+Outputs a graphviz dot file of the dependencies.
+"""
+
+from __future__ import print_function
+
+from optparse import make_option
+import re
+import textwrap
+
+from django.core.management.base import BaseCommand
+from django.core.management.color import no_style
+
+from south.migration import Migrations, all_migrations
+
+class Command(BaseCommand):
+
+ help = "Outputs a GraphViz dot file of all migration dependencies to stdout."
+
+ def handle(self, **options):
+
+ # Resolve dependencies
+ Migrations.calculate_dependencies()
+
+ colors = [ 'crimson', 'darkgreen', 'darkgoldenrod', 'navy',
+ 'brown', 'darkorange', 'aquamarine' , 'blueviolet' ]
+ color_index = 0
+ wrapper = textwrap.TextWrapper(width=40)
+
+ print("digraph G {")
+
+ # Group each app in a subgraph
+ for migrations in all_migrations():
+ print(" subgraph %s {" % migrations.app_label())
+ print(" node [color=%s];" % colors[color_index])
+ for migration in migrations:
+ # Munge the label - text wrap and change _ to spaces
+ label = "%s - %s" % (
+ migration.app_label(), migration.name())
+ label = re.sub(r"_+", " ", label)
+ label= "\\n".join(wrapper.wrap(label))
+ print(' "%s.%s" [label="%s"];' % (
+ migration.app_label(), migration.name(), label))
+ print(" }")
+ color_index = (color_index + 1) % len(colors)
+
+ # For every migration, print its links.
+ for migrations in all_migrations():
+ for migration in migrations:
+ for other in migration.dependencies:
+ # Added weight tends to keep migrations from the same app
+ # in vertical alignment
+ attrs = "[weight=2.0]"
+ # But the more interesting edges are those between apps
+ if other.app_label() != migration.app_label():
+ attrs = "[style=bold]"
+ print(' "%s.%s" -> "%s.%s" %s;' % (
+ other.app_label(), other.name(),
+ migration.app_label(), migration.name(),
+ attrs
+ ))
+
+ print("}");
diff --git a/lib/python2.7/site-packages/south/management/commands/migrate.py b/lib/python2.7/site-packages/south/management/commands/migrate.py
new file mode 100644
index 0000000..693dbb7
--- /dev/null
+++ b/lib/python2.7/site-packages/south/management/commands/migrate.py
@@ -0,0 +1,264 @@
+"""
+Migrate management command.
+"""
+
+from __future__ import print_function
+
+import os.path, re, sys
+from functools import reduce
+from optparse import make_option
+
+from django.core.management.base import BaseCommand
+from django.conf import settings
+from django.utils.importlib import import_module
+
+from south import migration
+from south.migration import Migrations
+from south.exceptions import NoMigrations
+from south.db import DEFAULT_DB_ALIAS
+
+class Command(BaseCommand):
+ option_list = BaseCommand.option_list + (
+ make_option('--all', action='store_true', dest='all_apps', default=False,
+ help='Run the specified migration for all apps.'),
+ make_option('--list', action='store_true', dest='show_list', default=False,
+ help='List migrations noting those that have been applied'),
+ make_option('--changes', action='store_true', dest='show_changes', default=False,
+ help='List changes for migrations'),
+ make_option('--skip', action='store_true', dest='skip', default=False,
+ help='Will skip over out-of-order missing migrations'),
+ make_option('--merge', action='store_true', dest='merge', default=False,
+ help='Will run out-of-order missing migrations as they are - no rollbacks.'),
+ make_option('--no-initial-data', action='store_true', dest='no_initial_data', default=False,
+ help='Skips loading initial data if specified.'),
+ make_option('--fake', action='store_true', dest='fake', default=False,
+ help="Pretends to do the migrations, but doesn't actually execute them."),
+ make_option('--db-dry-run', action='store_true', dest='db_dry_run', default=False,
+ help="Doesn't execute the SQL generated by the db methods, and doesn't store a record that the migration(s) occurred. Useful to test migrations before applying them."),
+ make_option('--delete-ghost-migrations', action='store_true', dest='delete_ghosts', default=False,
+ help="Tells South to delete any 'ghost' migrations (ones in the database but not on disk)."),
+ make_option('--ignore-ghost-migrations', action='store_true', dest='ignore_ghosts', default=False,
+ help="Tells South to ignore any 'ghost' migrations (ones in the database but not on disk) and continue to apply new migrations."),
+ 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.'),
+ )
+ if '--verbosity' not in [opt.get_opt_string() for opt in BaseCommand.option_list]:
+ option_list += (
+ make_option('--verbosity', action='store', dest='verbosity', default='1',
+ type='choice', choices=['0', '1', '2'],
+ help='Verbosity level; 0=minimal output, 1=normal output, 2=all output'),
+ )
+ help = "Runs migrations for all apps."
+ args = "[appname] [migrationname|zero] [--all] [--list] [--skip] [--merge] [--no-initial-data] [--fake] [--db-dry-run] [--database=dbalias]"
+
+ def handle(self, app=None, target=None, skip=False, merge=False, backwards=False, fake=False, db_dry_run=False, show_list=False, show_changes=False, database=DEFAULT_DB_ALIAS, delete_ghosts=False, ignore_ghosts=False, **options):
+
+ # NOTE: THIS IS DUPLICATED FROM django.core.management.commands.syncdb
+ # This code imports any module named 'management' in INSTALLED_APPS.
+ # The 'management' module is the preferred way of listening to post_syncdb
+ # signals, and since we're sending those out with create_table migrations,
+ # we need apps to behave correctly.
+ for app_name in settings.INSTALLED_APPS:
+ try:
+ import_module('.management', app_name)
+ except ImportError as exc:
+ msg = exc.args[0]
+ if not msg.startswith('No module named') or 'management' not in msg:
+ raise
+ # END DJANGO DUPE CODE
+
+ # if all_apps flag is set, shift app over to target
+ if options.get('all_apps', False):
+ target = app
+ app = None
+
+ # Migrate each app
+ if app:
+ try:
+ apps = [Migrations(app)]
+ except NoMigrations:
+ print("The app '%s' does not appear to use migrations." % app)
+ print("./manage.py migrate " + self.args)
+ return
+ else:
+ apps = list(migration.all_migrations())
+
+ # Do we need to show the list of migrations?
+ if show_list and apps:
+ list_migrations(apps, database, **options)
+
+ if show_changes and apps:
+ show_migration_changes(apps)
+
+ if not (show_list or show_changes):
+
+ for app in apps:
+ result = migration.migrate_app(
+ app,
+ target_name = target,
+ fake = fake,
+ db_dry_run = db_dry_run,
+ verbosity = int(options.get('verbosity', 0)),
+ interactive = options.get('interactive', True),
+ load_initial_data = not options.get('no_initial_data', False),
+ merge = merge,
+ skip = skip,
+ database = database,
+ delete_ghosts = delete_ghosts,
+ ignore_ghosts = ignore_ghosts,
+ )
+ if result is False:
+ sys.exit(1) # Migration failed, so the command fails.
+
+
+def list_migrations(apps, database = DEFAULT_DB_ALIAS, **options):
+ """
+ Prints a list of all available migrations, and which ones are currently applied.
+ Accepts a list of Migrations instances.
+ """
+ from south.models import MigrationHistory
+ applied_migrations = MigrationHistory.objects.filter(app_name__in=[app.app_label() for app in apps])
+ if database != DEFAULT_DB_ALIAS:
+ applied_migrations = applied_migrations.using(database)
+ applied_migrations_lookup = dict(('%s.%s' % (mi.app_name, mi.migration), mi) for mi in applied_migrations)
+
+ print()
+ for app in apps:
+ print(" " + app.app_label())
+ # Get the migrations object
+ for migration in app:
+ full_name = migration.app_label() + "." + migration.name()
+ if full_name in applied_migrations_lookup:
+ applied_migration = applied_migrations_lookup[full_name]
+ print(format_migration_list_item(migration.name(), applied=applied_migration.applied, **options))
+ else:
+ print(format_migration_list_item(migration.name(), applied=False, **options))
+ print()
+
+def show_migration_changes(apps):
+ """
+ Prints a list of all available migrations, and which ones are currently applied.
+ Accepts a list of Migrations instances.
+
+ Much simpler, less clear, and much less robust version:
+ grep "ing " migrations/*.py
+ """
+ for app in apps:
+ print(app.app_label())
+ # Get the migrations objects
+ migrations = [migration for migration in app]
+ # we use reduce to compare models in pairs, not to generate a value
+ reduce(diff_migrations, migrations)
+
+def format_migration_list_item(name, applied=True, **options):
+ if applied:
+ if int(options.get('verbosity')) >= 2:
+ return ' (*) %-80s (applied %s)' % (name, applied)
+ else:
+ return ' (*) %s' % name
+ else:
+ return ' ( ) %s' % name
+
+def diff_migrations(migration1, migration2):
+
+ def model_name(models, model):
+ return models[model].get('Meta', {}).get('object_name', model)
+
+ def field_name(models, model, field):
+ return '%s.%s' % (model_name(models, model), field)
+
+ print(" " + migration2.name())
+
+ models1 = migration1.migration_class().models
+ models2 = migration2.migration_class().models
+
+ # find new models
+ for model in models2.keys():
+ if not model in models1.keys():
+ print(' added model %s' % model_name(models2, model))
+
+ # find removed models
+ for model in models1.keys():
+ if not model in models2.keys():
+ print(' removed model %s' % model_name(models1, model))
+
+ # compare models
+ for model in models1:
+ if model in models2:
+
+ # find added fields
+ for field in models2[model]:
+ if not field in models1[model]:
+ print(' added field %s' % field_name(models2, model, field))
+
+ # find removed fields
+ for field in models1[model]:
+ if not field in models2[model]:
+ print(' removed field %s' % field_name(models1, model, field))
+
+ # compare fields
+ for field in models1[model]:
+ if field in models2[model]:
+
+ name = field_name(models1, model, field)
+
+ # compare field attributes
+ field_value1 = models1[model][field]
+ field_value2 = models2[model][field]
+
+ # if a field has become a class, or vice versa
+ if type(field_value1) != type(field_value2):
+ print(' type of %s changed from %s to %s' % (
+ name, field_value1, field_value2))
+
+ # if class
+ elif isinstance(field_value1, dict):
+ # print ' %s is a class' % name
+ pass
+
+ # else regular field
+ else:
+
+ type1, attr_list1, field_attrs1 = models1[model][field]
+ type2, attr_list2, field_attrs2 = models2[model][field]
+
+ if type1 != type2:
+ print(' %s type changed from %s to %s' % (
+ name, type1, type2))
+
+ if attr_list1 != []:
+ print(' %s list %s is not []' % (
+ name, attr_list1))
+ if attr_list2 != []:
+ print(' %s list %s is not []' % (
+ name, attr_list2))
+ if attr_list1 != attr_list2:
+ print(' %s list changed from %s to %s' % (
+ name, attr_list1, attr_list2))
+
+ # find added field attributes
+ for attr in field_attrs2:
+ if not attr in field_attrs1:
+ print(' added %s attribute %s=%s' % (
+ name, attr, field_attrs2[attr]))
+
+ # find removed field attributes
+ for attr in field_attrs1:
+ if not attr in field_attrs2:
+ print(' removed attribute %s(%s=%s)' % (
+ name, attr, field_attrs1[attr]))
+
+ # compare field attributes
+ for attr in field_attrs1:
+ if attr in field_attrs2:
+
+ value1 = field_attrs1[attr]
+ value2 = field_attrs2[attr]
+ if value1 != value2:
+ print(' %s attribute %s changed from %s to %s' % (
+ name, attr, value1, value2))
+
+ return migration2
diff --git a/lib/python2.7/site-packages/south/management/commands/migrationcheck.py b/lib/python2.7/site-packages/south/management/commands/migrationcheck.py
new file mode 100644
index 0000000..f498d0b
--- /dev/null
+++ b/lib/python2.7/site-packages/south/management/commands/migrationcheck.py
@@ -0,0 +1,67 @@
+from django.core.exceptions import ImproperlyConfigured
+from django.core.management import call_command, CommandError
+from django.core.management.base import BaseCommand
+from django.conf import settings
+from django.db.models import loading
+from django.test import simple
+
+from south.migration import Migrations
+from south.exceptions import NoMigrations
+from south.hacks import hacks
+
+class Command(BaseCommand):
+ help = "Runs migrations for each app in turn, detecting missing depends_on values."
+ usage_str = "Usage: ./manage.py migrationcheck"
+
+ def handle(self, check_app_name=None, **options):
+ runner = simple.DjangoTestSuiteRunner(verbosity=0)
+ err_msg = "Failed to migrate %s; see output for hints at missing dependencies:\n"
+ hacks.patch_flush_during_test_db_creation()
+ failures = 0
+ if check_app_name is None:
+ app_names = settings.INSTALLED_APPS
+ else:
+ app_names = [check_app_name]
+ for app_name in app_names:
+ app_label = app_name.split(".")[-1]
+ if app_name == 'south':
+ continue
+
+ try:
+ Migrations(app_name)
+ except (NoMigrations, ImproperlyConfigured):
+ continue
+ app = loading.get_app(app_label)
+
+ verbosity = int(options.get('verbosity', 1))
+ if verbosity >= 1:
+ self.stderr.write("processing %s\n" % app_name)
+
+ old_config = runner.setup_databases()
+ try:
+ call_command('migrate', app_label, noinput=True, verbosity=verbosity)
+ for model in loading.get_models(app):
+ dummy = model._default_manager.exists()
+ except (KeyboardInterrupt, SystemExit):
+ raise
+ except Exception as e:
+ failures += 1
+ if verbosity >= 1:
+ self.stderr.write(err_msg % app_name)
+ self.stderr.write("%s\n" % e)
+ finally:
+ runner.teardown_databases(old_config)
+ if failures > 0:
+ raise CommandError("Missing depends_on found in %s app(s)." % failures)
+ self.stderr.write("No missing depends_on found.\n")
+#
+#for each app:
+# start with blank db.
+# syncdb only south (and contrib?)
+#
+# migrate a single app all the way up. any errors is missing depends_on.
+# for all models of that app, try the default manager:
+# from django.db.models import loading
+# for m in loading.get_models(loading.get_app('a')):
+# m._default_manager.exists()
+# Any error is also a missing depends on.
diff --git a/lib/python2.7/site-packages/south/management/commands/schemamigration.py b/lib/python2.7/site-packages/south/management/commands/schemamigration.py
new file mode 100644
index 0000000..efd4266
--- /dev/null
+++ b/lib/python2.7/site-packages/south/management/commands/schemamigration.py
@@ -0,0 +1,229 @@
+"""
+Startmigration command, version 2.
+"""
+
+from __future__ import print_function
+
+import sys
+import os
+import re
+import string
+import random
+import inspect
+from optparse import make_option
+
+try:
+ set
+except NameError:
+ from sets import Set as set
+
+from django.core.management.base import BaseCommand
+from django.core.management.color import no_style
+from django.core.exceptions import ImproperlyConfigured
+from django.db import models
+from django.conf import settings
+
+from south.migration import Migrations, migrate_app
+from south.models import MigrationHistory
+from south.exceptions import NoMigrations
+from south.creator import changes, actions, freezer
+from south.management.commands.datamigration import Command as DataCommand
+
+class Command(DataCommand):
+ option_list = DataCommand.option_list + (
+ make_option('--add-model', action='append', dest='added_model_list', type='string',
+ help='Generate a Create Table migration for the specified model. Add multiple models to this migration with subsequent --add-model parameters.'),
+ make_option('--add-field', action='append', dest='added_field_list', type='string',
+ help='Generate an Add Column migration for the specified modelname.fieldname - you can use this multiple times to add more than one column.'),
+ make_option('--add-index', action='append', dest='added_index_list', type='string',
+ help='Generate an Add Index migration for the specified modelname.fieldname - you can use this multiple times to add more than one column.'),
+ make_option('--initial', action='store_true', dest='initial', default=False,
+ help='Generate the initial schema for the app.'),
+ make_option('--auto', action='store_true', dest='auto', default=False,
+ help='Attempt to automatically detect differences from the last migration.'),
+ make_option('--empty', action='store_true', dest='empty', default=False,
+ help='Make a blank migration.'),
+ make_option('--update', action='store_true', dest='update', default=False,
+ help='Update the most recent migration instead of creating a new one. Rollback this migration if it is already applied.'),
+ )
+ help = "Creates a new template schema migration for the given app"
+ usage_str = "Usage: ./manage.py schemamigration appname migrationname [--empty] [--initial] [--auto] [--add-model ModelName] [--add-field ModelName.field_name] [--stdout]"
+
+ def handle(self, app=None, name="", added_model_list=None, added_field_list=None, freeze_list=None, initial=False, auto=False, stdout=False, added_index_list=None, verbosity=1, empty=False, update=False, **options):
+
+ # Any supposed lists that are None become empty lists
+ added_model_list = added_model_list or []
+ added_field_list = added_field_list or []
+ added_index_list = added_index_list or []
+ freeze_list = freeze_list or []
+
+ # --stdout means name = -
+ if stdout:
+ name = "-"
+
+ # Only allow valid names
+ if re.search('[^_\w]', name) and name != "-":
+ self.error("Migration names should contain only alphanumeric characters and underscores.")
+
+ # Make sure options are compatable
+ if initial and (added_model_list or added_field_list or auto):
+ self.error("You cannot use --initial and other options together\n" + self.usage_str)
+
+ if auto and (added_model_list or added_field_list or initial):
+ self.error("You cannot use --auto and other options together\n" + self.usage_str)
+
+ if not app:
+ self.error("You must provide an app to create a migration for.\n" + self.usage_str)
+
+ # See if the app exists
+ app = app.split(".")[-1]
+ try:
+ app_module = models.get_app(app)
+ except ImproperlyConfigured:
+ print("There is no enabled application matching '%s'." % app)
+ return
+
+ # Get the Migrations for this app (creating the migrations dir if needed)
+ migrations = Migrations(app, force_creation=True, verbose_creation=int(verbosity) > 0)
+
+ # What actions do we need to do?
+ if auto:
+ # Get the old migration
+ try:
+ last_migration = migrations[-2 if update else -1]
+ except IndexError:
+ self.error("You cannot use --auto on an app with no migrations. Try --initial.")
+ # Make sure it has stored models
+ if migrations.app_label() not in getattr(last_migration.migration_class(), "complete_apps", []):
+ self.error("You cannot use automatic detection, since the previous migration does not have this whole app frozen.\nEither make migrations using '--freeze %s' or set 'SOUTH_AUTO_FREEZE_APP = True' in your settings.py." % migrations.app_label())
+ # Alright, construct two model dicts to run the differ on.
+ old_defs = dict(
+ (k, v) for k, v in last_migration.migration_class().models.items()
+ if k.split(".")[0] == migrations.app_label()
+ )
+ new_defs = dict(
+ (k, v) for k, v in freezer.freeze_apps([migrations.app_label()]).items()
+ if k.split(".")[0] == migrations.app_label()
+ )
+ change_source = changes.AutoChanges(
+ migrations = migrations,
+ old_defs = old_defs,
+ old_orm = last_migration.orm(),
+ new_defs = new_defs,
+ )
+
+ elif initial:
+ # Do an initial migration
+ change_source = changes.InitialChanges(migrations)
+
+ else:
+ # Read the commands manually off of the arguments
+ if (added_model_list or added_field_list or added_index_list):
+ change_source = changes.ManualChanges(
+ migrations,
+ added_model_list,
+ added_field_list,
+ added_index_list,
+ )
+ elif empty:
+ change_source = None
+ else:
+ print("You have not passed any of --initial, --auto, --empty, --add-model, --add-field or --add-index.", file=sys.stderr)
+ sys.exit(1)
+
+ # Validate this so we can access the last migration without worrying
+ if update and not migrations:
+ self.error("You cannot use --update on an app with no migrations.")
+
+ # if not name, there's an error
+ if not name:
+ if change_source:
+ name = change_source.suggest_name()
+ if update:
+ name = re.sub(r'^\d{4}_', '', migrations[-1].name())
+ if not name:
+ self.error("You must provide a name for this migration\n" + self.usage_str)
+
+ # Get the actions, and then insert them into the actions lists
+ forwards_actions = []
+ backwards_actions = []
+ if change_source:
+ for action_name, params in change_source.get_changes():
+ # Run the correct Action class
+ try:
+ action_class = getattr(actions, action_name)
+ except AttributeError:
+ raise ValueError("Invalid action name from source: %s" % action_name)
+ else:
+ action = action_class(**params)
+ action.add_forwards(forwards_actions)
+ action.add_backwards(backwards_actions)
+ print(action.console_line(), file=sys.stderr)
+
+ # Nowt happen? That's not good for --auto.
+ if auto and not forwards_actions:
+ self.error("Nothing seems to have changed.")
+
+ # Work out which apps to freeze
+ apps_to_freeze = self.calc_frozen_apps(migrations, freeze_list)
+
+ # So, what's in this file, then?
+ file_contents = self.get_migration_template() % {
+ "forwards": "\n".join(forwards_actions or [" pass"]),
+ "backwards": "\n".join(backwards_actions or [" pass"]),
+ "frozen_models": freezer.freeze_apps_to_string(apps_to_freeze),
+ "complete_apps": apps_to_freeze and "complete_apps = [%s]" % (", ".join(map(repr, apps_to_freeze))) or ""
+ }
+
+ # Deal with update mode as late as possible, avoid a rollback as long
+ # as something else can go wrong.
+ if update:
+ last_migration = migrations[-1]
+ if MigrationHistory.objects.filter(applied__isnull=False, app_name=app, migration=last_migration.name()):
+ print("Migration to be updated, %s, is already applied, rolling it back now..." % last_migration.name(), file=sys.stderr)
+ migrate_app(migrations, 'current-1', verbosity=verbosity)
+ for ext in ('py', 'pyc'):
+ old_filename = "%s.%s" % (os.path.join(migrations.migrations_dir(), last_migration.filename), ext)
+ if os.path.isfile(old_filename):
+ os.unlink(old_filename)
+ migrations.remove(last_migration)
+
+ # See what filename is next in line. We assume they use numbers.
+ new_filename = migrations.next_filename(name)
+
+ # - is a special name which means 'print to stdout'
+ if name == "-":
+ print(file_contents)
+ # Write the migration file if the name isn't -
+ else:
+ fp = open(os.path.join(migrations.migrations_dir(), new_filename), "w")
+ fp.write(file_contents)
+ fp.close()
+ verb = 'Updated' if update else 'Created'
+ if empty:
+ print("%s %s. You must now edit this migration and add the code for each direction." % (verb, new_filename), file=sys.stderr)
+ else:
+ print("%s %s. You can now apply this migration with: ./manage.py migrate %s" % (verb, new_filename, app), file=sys.stderr)
+
+ def get_migration_template(self):
+ return MIGRATION_TEMPLATE
+
+
+MIGRATION_TEMPLATE = """# -*- coding: utf-8 -*-
+from south.utils import datetime_utils as datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+%(forwards)s
+
+ def backwards(self, orm):
+%(backwards)s
+
+ models = %(frozen_models)s
+
+ %(complete_apps)s"""
diff --git a/lib/python2.7/site-packages/south/management/commands/startmigration.py b/lib/python2.7/site-packages/south/management/commands/startmigration.py
new file mode 100644
index 0000000..e4fcf45
--- /dev/null
+++ b/lib/python2.7/site-packages/south/management/commands/startmigration.py
@@ -0,0 +1,33 @@
+"""
+Now-obsolete startmigration command.
+"""
+
+from __future__ import print_function
+
+from optparse import make_option
+
+from django.core.management.base import BaseCommand
+from django.core.management.color import no_style
+
+class Command(BaseCommand):
+ option_list = BaseCommand.option_list + (
+ make_option('--model', action='append', dest='added_model_list', type='string',
+ help='Generate a Create Table migration for the specified model. Add multiple models to this migration with subsequent --add-model parameters.'),
+ make_option('--add-field', action='append', dest='added_field_list', type='string',
+ help='Generate an Add Column migration for the specified modelname.fieldname - you can use this multiple times to add more than one column.'),
+ make_option('--add-index', action='append', dest='added_index_list', type='string',
+ help='Generate an Add Index migration for the specified modelname.fieldname - you can use this multiple times to add more than one column.'),
+ make_option('--initial', action='store_true', dest='initial', default=False,
+ help='Generate the initial schema for the app.'),
+ make_option('--auto', action='store_true', dest='auto', default=False,
+ help='Attempt to automatically detect differences from the last migration.'),
+ make_option('--freeze', action='append', dest='freeze_list', type='string',
+ help='Freeze the specified model(s). Pass in either an app name (to freeze the whole app) or a single model, as appname.modelname.'),
+ make_option('--stdout', action='store_true', dest='stdout', default=False,
+ help='Print the migration to stdout instead of writing it to a file.'),
+ )
+ help = "Deprecated command"
+
+ def handle(self, app=None, name="", added_model_list=None, added_field_list=None, initial=False, freeze_list=None, auto=False, stdout=False, added_index_list=None, **options):
+
+ print("The 'startmigration' command is now deprecated; please use the new 'schemamigration' and 'datamigration' commands.")
diff --git a/lib/python2.7/site-packages/south/management/commands/syncdb.py b/lib/python2.7/site-packages/south/management/commands/syncdb.py
new file mode 100644
index 0000000..17fc22c
--- /dev/null
+++ b/lib/python2.7/site-packages/south/management/commands/syncdb.py
@@ -0,0 +1,115 @@
+"""
+Overridden syncdb command
+"""
+
+from __future__ import print_function
+
+import sys
+from optparse import make_option
+
+from django.core.management.base import NoArgsCommand, BaseCommand
+from django.core.management.color import no_style
+from django.utils.datastructures import SortedDict
+from django.core.management.commands import syncdb
+from django.conf import settings
+from django.db import models
+from django.db.models.loading import cache
+from django.core import management
+
+from south.db import dbs
+from south import migration
+from south.exceptions import NoMigrations
+
+def get_app_label(app):
+ return '.'.join( app.__name__.split('.')[0:-1] )
+
+class Command(NoArgsCommand):
+ option_list = syncdb.Command.option_list + (
+ make_option('--migrate', action='store_true', dest='migrate', default=False,
+ help='Tells South to also perform migrations after the sync. Default for during testing, and other internal calls.'),
+ make_option('--all', action='store_true', dest='migrate_all', default=False,
+ help='Makes syncdb work on all apps, even migrated ones. Be careful!'),
+ )
+ if '--verbosity' not in [opt.get_opt_string() for opt in syncdb.Command.option_list]:
+ option_list += (
+ make_option('--verbosity', action='store', dest='verbosity', default='1',
+ type='choice', choices=['0', '1', '2'],
+ help='Verbosity level; 0=minimal output, 1=normal output, 2=all output'),
+ )
+ help = "Create the database tables for all apps in INSTALLED_APPS whose tables haven't already been created, except those which use migrations."
+
+ def handle_noargs(self, migrate_all=False, **options):
+
+ # Import the 'management' module within each installed app, to register
+ # dispatcher events.
+ # This is copied from Django, to fix bug #511.
+ try:
+ from django.utils.importlib import import_module
+ except ImportError:
+ pass # TODO: Remove, only for Django1.0
+ else:
+ for app_name in settings.INSTALLED_APPS:
+ try:
+ import_module('.management', app_name)
+ except ImportError as exc:
+ msg = exc.args[0]
+ if not msg.startswith('No module named') or 'management' not in msg:
+ raise
+
+ # Work out what uses migrations and so doesn't need syncing
+ apps_needing_sync = []
+ apps_migrated = []
+ for app in models.get_apps():
+ app_label = get_app_label(app)
+ if migrate_all:
+ apps_needing_sync.append(app_label)
+ else:
+ try:
+ migrations = migration.Migrations(app_label)
+ except NoMigrations:
+ # It needs syncing
+ apps_needing_sync.append(app_label)
+ else:
+ # This is a migrated app, leave it
+ apps_migrated.append(app_label)
+ verbosity = int(options.get('verbosity', 0))
+
+ # Run syncdb on only the ones needed
+ if verbosity:
+ print("Syncing...")
+
+ old_installed, settings.INSTALLED_APPS = settings.INSTALLED_APPS, apps_needing_sync
+ old_app_store, cache.app_store = cache.app_store, SortedDict([
+ (k, v) for (k, v) in cache.app_store.items()
+ if get_app_label(k) in apps_needing_sync
+ ])
+
+ # This will allow the setting of the MySQL storage engine, for example.
+ for db in dbs.values():
+ db.connection_init()
+
+ # OK, run the actual syncdb
+ syncdb.Command().execute(**options)
+
+ settings.INSTALLED_APPS = old_installed
+ cache.app_store = old_app_store
+
+ # Migrate if needed
+ if options.get('migrate', True):
+ if verbosity:
+ print("Migrating...")
+ # convert from store_true to store_false
+ options['no_initial_data'] = not options.get('load_initial_data', True)
+ management.call_command('migrate', **options)
+
+ # Be obvious about what we did
+ if verbosity:
+ print("\nSynced:\n > %s" % "\n > ".join(apps_needing_sync))
+
+ if options.get('migrate', True):
+ if verbosity:
+ print("\nMigrated:\n - %s" % "\n - ".join(apps_migrated))
+ else:
+ if verbosity:
+ print("\nNot synced (use migrations):\n - %s" % "\n - ".join(apps_migrated))
+ print("(use ./manage.py migrate to migrate these)")
diff --git a/lib/python2.7/site-packages/south/management/commands/test.py b/lib/python2.7/site-packages/south/management/commands/test.py
new file mode 100644
index 0000000..9901786
--- /dev/null
+++ b/lib/python2.7/site-packages/south/management/commands/test.py
@@ -0,0 +1,8 @@
+from django.core.management.commands import test
+
+from south.management.commands import patch_for_test_db_setup
+
+class Command(test.Command):
+ def handle(self, *args, **kwargs):
+ patch_for_test_db_setup()
+ super(Command, self).handle(*args, **kwargs)
diff --git a/lib/python2.7/site-packages/south/management/commands/testserver.py b/lib/python2.7/site-packages/south/management/commands/testserver.py
new file mode 100644
index 0000000..3c3c4b5
--- /dev/null
+++ b/lib/python2.7/site-packages/south/management/commands/testserver.py
@@ -0,0 +1,8 @@
+from django.core.management.commands import testserver
+
+from south.management.commands import patch_for_test_db_setup
+
+class Command(testserver.Command):
+ def handle(self, *args, **kwargs):
+ patch_for_test_db_setup()
+ super(Command, self).handle(*args, **kwargs)