Beispiel #1
0
def create_orm():
    from django.conf import settings
    from south.orm import FakeORM

    get_migration_number_re = re.compile(r'^((\d+)_.*)\.py$')

    migrations_folder = os.path.join(settings.SITE_SRC_ROOT,
                                     'forum/migrations')

    highest_number = 0
    highest_file = None

    for f in os.listdir(migrations_folder):
        if os.path.isfile(os.path.join(migrations_folder, f)):
            m = get_migration_number_re.match(f)

            if m:
                found = int(m.group(2))

                if found > highest_number:
                    highest_number = found
                    highest_file = m.group(1)

    mod = __import__('forum.migrations.%s' % highest_file, globals(), locals(),
                     ['forum.migrations'])
    return FakeORM(getattr(mod, 'Migration'), "forum")
Beispiel #2
0
    def test_not_deleted_auto(self):

        empty_defs = {}
        old_defs = freezer.freeze_apps(["non_managed"])

        class InitialMigration(SchemaMigration):
            "Serves as fake previous migration"

            def forwards(self, orm):
                pass

            def backwards(self, orm):
                pass

            models = self.full_defs

            complete_apps = ['non_managed']

        migrations = Migrations("non_managed")
        initial_orm = FakeORM(InitialMigration, "non_managed")
        changes = AutoChanges(
            migrations=migrations,
            old_defs=self.full_defs,
            old_orm=initial_orm,
            new_defs=empty_defs,
        )
        change_list = changes.get_changes()
        if list(change_list):
            self.fail("Auto migration deletes table for non-managed model")
Beispiel #3
0
    def test_not_added_auto(self):

        empty_defs = {}

        class EmptyMigration(SchemaMigration):
            "Serves as fake previous migration"

            def forwards(self, orm):
                pass

            def backwards(self, orm):
                pass

            models = empty_defs

            complete_apps = ['non_managed']

        migrations = Migrations("non_managed")
        empty_orm = FakeORM(EmptyMigration, "non_managed")
        changes = AutoChanges(
            migrations=migrations,
            old_defs=empty_defs,
            old_orm=empty_orm,
            new_defs=self.full_defs,
        )
        change_list = changes.get_changes()
        if list(change_list):
            self.fail("Auto migration creates table for non-managed model")
Beispiel #4
0
 def prev_orm(self):
     if getattr(self.migration_class(), 'symmetrical', False):
         return self.orm()
     previous = self.previous()
     if previous is None:
         # First migration? The 'previous ORM' is empty.
         return FakeORM(None, self.app_label())
     return previous.orm()
Beispiel #5
0
    def get_indexes(self):
        # TODO: не удаляются индексы у внешних ключей и добавочные
        # _like-индексы к ним. Например у House
        migration = Migrations('fias', force_creation=True)
        # получим текущее состояние базы
        new_defs = dict(
            (k, v)
            for k, v in freezer.freeze_apps([migration.app_label()]).items()
            if k.split(".")[0] == migration.app_label())
        # скопируем и удалим все индексы
        old_defs = copy.deepcopy(new_defs)
        for table in old_defs.values():
            for key, value in table.items():
                # удалим 'index_together'
                if key == 'Meta' and 'index_together' in value:
                    del value['index_together']
                if isinstance(value, tuple):
                    # удалим 'unique'
                    if 'unique' in value[2]:
                        value[2]['unique'] = False
                    # удалим 'db_index'
                    if 'db_index' in value[2]:
                        value[2]['db_index'] = False

        class InitialMigration(SchemaMigration):
            def forwards(self, orm):
                pass

            def backwards(self, orm):
                pass

            models = old_defs
            complete_apps = ['fias']

        initial_orm = FakeORM(InitialMigration, "fias")

        # получим все изменения, т.е. список индексов
        change_source = changes.AutoChanges(
            migrations=migration,
            old_defs=old_defs,
            old_orm=initial_orm,
            new_defs=new_defs,
        )

        for action_name, params in change_source.get_changes():
            try:
                action_class = getattr(actions, action_name)
            except AttributeError:
                raise ValueError("Invalid action name from source: %s" %
                                 action_name)
            else:
                if issubclass(action_class, AddUnique):
                    yield action_class, params
Beispiel #6
0
    def test_not_modified_auto(self):

        fake_defs = {
            'non_managed.legacy': {
                'Meta': {
                    'object_name': 'Legacy',
                    'db_table': "'legacy_table'",
                    'managed': 'False'
                },
                'id': ('django.db.models.fields.AutoField', [], {
                    'primary_key': 'True'
                }),
                'name': ('django.db.models.fields.CharField', [], {
                    'max_length': '10',
                    'null': 'True'
                }),
                #'size': ('django.db.models.fields.IntegerField', [], {}) # The "change" is the addition of this field
            }
        }

        class InitialMigration(SchemaMigration):
            "Serves as fake previous migration"

            def forwards(self, orm):
                pass

            def backwards(self, orm):
                pass

            models = fake_defs

            complete_apps = ['non_managed']

        from non_managed import models as dummy_import_to_force_loading_models  # TODO: Does needing this indicate a bug in MokeyPatcher?
        reload_module(dummy_import_to_force_loading_models)  # really force...

        migrations = Migrations("non_managed")
        initial_orm = FakeORM(InitialMigration, "non_managed")
        changes = AutoChanges(migrations=migrations,
                              old_defs=fake_defs,
                              old_orm=initial_orm,
                              new_defs=self.full_defs)
        change_list = changes.get_changes()
        if list(change_list):
            self.fail("Auto migration changes table for non-managed model")
Beispiel #7
0
def get_migration(app, name):
    """
    Returns the migration class implied by 'name'.
    """
    try:
        module = __import__(app.__name__ + "." + name, '', '', ['Migration'])
        migclass = module.Migration
        migclass.orm = FakeORM(migclass, get_app_name(app))
        module._ = lambda x: x  # Fake i18n
        return migclass
    except ImportError:
        print " ! Migration %s:%s probably doesn't exist." % (
            get_app_name(app), name)
        print " - Traceback:"
        raise
    except Exception, e:
        print "While loading migration '%s.%s':" % (get_app_name(app), name)
        raise
Beispiel #8
0
def run_migrations(toprint, torun, recorder, app, migrations, fake=False, db_dry_run=False, verbosity=0):
    """
    Runs the specified migrations forwards/backwards, in order.
    """
    for migration in migrations:
        app_name = get_app_name(app)
        if verbosity:
            print toprint % (app_name, migration)
        
        # Get migration class
        klass = get_migration(app, migration)
        # Find its predecessor, and attach the ORM from that as prev_orm.
        all_names = get_migration_names(app)
        idx = all_names.index(migration)
        # First migration? The 'previous ORM' is empty.
        if idx == 0:
            klass.prev_orm = FakeORM(None, app)
        else:
            klass.prev_orm = get_migration(app, all_names[idx-1]).orm
        
        # If this is a 'fake' migration, do nothing.
        if fake:
            if verbosity:
                print "   (faked)"
        
        # OK, we should probably do something then.
        else:
            runfunc = getattr(klass(), torun)
            args = inspect.getargspec(runfunc)
            
            # Get the correct ORM.
            if torun == "forwards":
                orm = klass.orm
            else:
                orm = klass.prev_orm
            
            db.current_orm = orm
            
            # If the database doesn't support running DDL inside a transaction
            # *cough*MySQL*cough* then do a dry run first.
            if not db.has_ddl_transactions or db_dry_run:
                if not (hasattr(klass, "no_dry_run") and klass.no_dry_run):
                    db.dry_run = True
                    # Only hide SQL if this is an automatic dry run.
                    if not db.has_ddl_transactions:
                        db.debug, old_debug = False, db.debug
                    pending_creates = db.get_pending_creates()
                    db.start_transaction()
                    try:
                        if len(args[0]) == 1:  # They don't want an ORM param
                            runfunc()
                        else:
                            runfunc(orm)
                            db.rollback_transactions_dry_run()
                    except:
                        traceback.print_exc()
                        print " ! Error found during dry run of migration! Aborting."
                        return False
                    if not db.has_ddl_transactions:
                        db.debug = old_debug
                    db.clear_run_data(pending_creates)
                    db.dry_run = False
                elif db_dry_run:
                    print " - Migration '%s' is marked for no-dry-run." % migration
                # If they really wanted to dry-run, then quit!
                if db_dry_run:
                    return
            
            if db.has_ddl_transactions:
                db.start_transaction()
            try:
                if len(args[0]) == 1:  # They don't want an ORM param
                    runfunc()
                else:
                    runfunc(orm)
                db.execute_deferred_sql()
            except:
                if db.has_ddl_transactions:
                    db.rollback_transaction()
                    raise
                else:
                    traceback.print_exc()
                    print " ! Error found during real run of migration! Aborting."
                    print
                    print " ! Since you have a database that does not support running"
                    print " ! schema-altering statements in transactions, we have had to"
                    print " ! leave it in an interim state between migrations."
                    if torun == "forwards":
                        print
                        print " ! You *might* be able to recover with:"
                        db.debug = db.dry_run = True
                        if len(args[0]) == 1:
                            klass().backwards()
                        else:
                            klass().backwards(klass.prev_orm)
                    print
                    print " ! The South developers regret this has happened, and would"
                    print " ! like to gently persuade you to consider a slightly"
                    print " ! easier-to-deal-with DBMS."
                    return False
            else:
                if db.has_ddl_transactions:
                    db.commit_transaction()

        if not db_dry_run:
            # Record us as having done this
            recorder(app_name, migration)
            if not fake:
                # Send a signal saying it ran
                # Actually, don't - we're implementing this properly in 0.7
                #ran_migration.send(None, app=app_name, migration=migration, method=torun)
                pass
Beispiel #9
0
 def orm(self):
     return FakeORM(self.migration_class(), self.app_label())
Beispiel #10
0
 def prev_orm(self):
     previous = self.previous()
     if previous is None:
         # First migration? The 'previous ORM' is empty.
         return FakeORM(None, self.app_label())
     return previous.orm()
def apply_south_migration(migration_cls, *_args, **_kwargs):
    orm = FakeORM(migration_cls, 'testapp')
    migration_instance = migration_cls()
    migration_instance.forwards(orm)
Beispiel #12
0
            'Meta': {'unique_together': "(('user', 'key'),)", 'object_name': 'UserProperty'},
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'key': ('django.db.models.fields.CharField', [], {'max_length': '16'}),
            'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'properties'", 'to': "orm['forum.User']"}),
            'value': ('forum.models.utils.PickledObjectField', [], {'null': 'True'})
        },
        'forum.validationhash': {
            'Meta': {'unique_together': "(('user', 'type'),)", 'object_name': 'ValidationHash'},
            'expiration': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2010, 7, 2, 13, 6, 46, 883626)'}),
            'hash_code': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'seed': ('django.db.models.fields.CharField', [], {'max_length': '12'}),
            'type': ('django.db.models.fields.CharField', [], {'max_length': '12'}),
            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.User']"})
        },
        'forum.vote': {
            'Meta': {'unique_together': "(('user', 'node'),)", 'object_name': 'Vote'},
            'action': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'vote'", 'unique': 'True', 'to': "orm['forum.Action']"}),
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'node': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'votes'", 'to': "orm['forum.Node']"}),
            'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'votes'", 'to': "orm['forum.User']"}),
            'value': ('django.db.models.fields.SmallIntegerField', [], {}),
            'voted_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'})
        }
    }

    complete_apps = ['forum']

orm = FakeORM(Migration, "forum")