Beispiel #1
0
    def test_alter_column_null(self):
        def null_ok():
            from django.db import connection, transaction
            # the DBAPI introspection module fails on postgres NULLs.
            cursor = connection.cursor()
            try:
                cursor.execute("INSERT INTO southtest_spam (id, weight, expires, name) VALUES (100, 10.1, now(), NULL);")
            except:
                transaction.rollback()
                return False
            else:
                cursor.execute("DELETE FROM southtest_spam")
                transaction.commit()
                return True
        
        app = migration.get_app("fakeapp")
        tree = migration.dependency_tree()
        self.assertEqual(list(migration.MigrationHistory.objects.all()), [])
        
        # by default name is NOT NULL
        migration.migrate_app(app, tree, target_name="0002", resolve_mode=None, fake=False, verbosity=0)
        self.failIf(null_ok())
        
        # after 0003, it should be NULL
        migration.migrate_app(app, tree, target_name="0003", resolve_mode=None, fake=False, verbosity=0)
        self.assert_(null_ok())

        # make sure it is NOT NULL again
        migration.migrate_app(app, tree, target_name="0002", resolve_mode=None, fake=False, verbosity=0)
        self.failIf(null_ok(), 'name not null after migration')
        
        # finish with no migrations, otherwise other tests fail...
        migration.migrate_app(app, tree, target_name="zero", resolve_mode=None, fake=False, verbosity=0)
        self.assertEqual(list(migration.MigrationHistory.objects.all()), [])
Beispiel #2
0
 def test_migration_merge_forwards(self):
     migration.MigrationHistory.objects.all().delete()
     app = migration.get_app("fakeapp")
     
     # We should start with no migrations
     self.assertEqual(list(migration.MigrationHistory.objects.all()), [])
     
     # Insert one in the wrong order
     migration.MigrationHistory.objects.create(
         app_name = "fakeapp",
         migration = "0002_eggs",
         applied = datetime.datetime.now(),
     )
     
     # Did it go in?
     self.assertListEqual(
         (
             (u"fakeapp", u"0002_eggs"),
         ),
         migration.MigrationHistory.objects.values_list("app_name", "migration"),
     )
     
     # Apply them normally
     tree = migration.dependency_tree()
     try:
         # Redirect the error it will print to nowhere
         stdout, sys.stdout = sys.stdout, StringIO.StringIO()
         migration.migrate_app(app, tree, target_name=None, resolve_mode=None, fake=False, verbosity=0)
         sys.stdout = stdout
     except SystemExit:
         pass
     
     # Nothing should have changed (no merge mode!)
     self.assertListEqual(
         (
             (u"fakeapp", u"0002_eggs"),
         ),
         migration.MigrationHistory.objects.values_list("app_name", "migration"),
     )
     
     # Apply with merge
     migration.migrate_app(app, tree, target_name=None, resolve_mode="merge", fake=False, verbosity=0)
     
     # We should finish with all migrations
     self.assertListEqual(
         (
             (u"fakeapp", u"0001_spam"),
             (u"fakeapp", u"0002_eggs"),
             (u"fakeapp", u"0003_alter_spam"),
         ),
         migration.MigrationHistory.objects.values_list("app_name", "migration"),
     )
     
     # Now roll them backwards
     migration.migrate_app(app, tree, target_name="0002", resolve_mode=None, fake=False, verbosity=0)
     migration.migrate_app(app, tree, target_name="0001", resolve_mode=None, fake=True, verbosity=0)
     migration.migrate_app(app, tree, target_name="zero", resolve_mode=None, fake=False, verbosity=0)
     
     # Finish with none
     self.assertEqual(list(migration.MigrationHistory.objects.all()), [])
Beispiel #3
0
 def test_apply_migrations(self):
     migration.MigrationHistory.objects.all().delete()
     app = migration.get_app("fakeapp")
     
     # We should start with no migrations
     self.assertEqual(list(migration.MigrationHistory.objects.all()), [])
     
     # Apply them normally
     tree = migration.dependency_tree()
     migration.migrate_app(app, tree, target_name=None, resolve_mode=None, fake=False, verbosity=0)
     
     # We should finish with all migrations
     self.assertListEqual(
         (
             (u"fakeapp", u"0001_spam"),
             (u"fakeapp", u"0002_eggs"),
             (u"fakeapp", u"0003_alter_spam"),
         ),
         migration.MigrationHistory.objects.values_list("app_name", "migration"),
     )
     
     # Now roll them backwards
     migration.migrate_app(app, tree, target_name="zero", resolve_mode=None, fake=False, verbosity=0)
     
     # Finish with none
     self.assertEqual(list(migration.MigrationHistory.objects.all()), [])
Beispiel #4
0
    def test_dependencies(self):

        fakeapp = migration.get_app("fakeapp")
        otherfakeapp = migration.get_app("otherfakeapp")

        # Test a simple path
        tree = migration.dependency_tree()
        self.assertEqual(
            map(
                snd,
                migration.needed_before_forwards(tree, fakeapp,
                                                 "0003_alter_spam")),
            ['0001_spam', '0002_eggs'],
        )

        # And a complex one, with both back and forwards deps
        self.assertEqual(
            map(
                snd,
                migration.needed_before_forwards(tree, otherfakeapp,
                                                 "0003_third")),
            [
                '0001_spam', '0001_first', '0002_second', '0002_eggs',
                '0003_alter_spam'
            ],
        )
Beispiel #5
0
 def test_dependencies(self):
     
     fakeapp = migration.get_app("fakeapp")
     otherfakeapp = migration.get_app("otherfakeapp")
     
     # Test a simple path
     tree = migration.dependency_tree()
     self.assertEqual(
         map(snd, migration.needed_before_forwards(tree, fakeapp, "0003_alter_spam")),
         ['0001_spam', '0002_eggs'],
     )
     
     # And a complex one, with both back and forwards deps
     self.assertEqual(
         map(snd, migration.needed_before_forwards(tree, otherfakeapp, "0003_third")),
         ['0001_spam', '0001_first', '0002_second', '0002_eggs', '0003_alter_spam'],
     )
Beispiel #6
0
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='list', default=False,
            help='List migrations noting those that have been applied'),
        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."),
    )
    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]"

    def handle(self, app=None, target=None, skip=False, merge=False, backwards=False, fake=False, db_dry_run=False, list=False, **options):

        # Work out what the resolve mode is
        resolve_mode = merge and "merge" or (skip and "skip" or None)
        
        # 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__(app_name + '.management', {}, {}, [''])
            except ImportError, 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:
            apps = [migration.get_app(app.split(".")[-1])]
            if apps == [None]:
                print "The app '%s' does not appear to use migrations." % app
                print "./manage.py migrate " + self.args
                return
        else:
            apps = migration.get_migrated_apps()
        
        if list and apps:
            list_migrations(apps)
        
        if not list:
            tree = migration.dependency_tree()
            
            for app in apps:
                result = migration.migrate_app(
                    app,
                    tree,
                    resolve_mode = resolve_mode,
                    target_name = target,
                    fake = fake,
                    db_dry_run = db_dry_run,
                    verbosity = int(options.get('verbosity', 0)),
                    load_inital_data = not options.get('no_initial_data', False),
                    skip = skip,
                )
                if result is False:
                    return