Ejemplo n.º 1
0
 def _run_migration(self, migration):
     if migration.no_dry_run() and self.verbosity:
         print " - Migration '%s' is marked for no-dry-run."
         return
     db.dry_run = True
     db.debug, old_debug = False, db.debug
     pending_creates = db.get_pending_creates()
     db.start_transaction()
     migration_function = self.direction(migration)
     try:
         try:
             migration_function()
         except:
             raise exceptions.FailedDryRun(migration, sys.exc_info())
     finally:
         db.rollback_transactions_dry_run()
         db.debug = old_debug
         db.clear_run_data(pending_creates)
         db.dry_run = False
Ejemplo n.º 2
0
 def _run_migration(self, migration):
     if migration.no_dry_run() and self.verbosity:
         print " - Migration '%s' is marked for no-dry-run."
         return
     db.dry_run = True
     db.debug, old_debug = False, db.debug
     pending_creates = db.get_pending_creates()
     db.start_transaction()
     migration_function = self.direction(migration)
     try:
         try:
             migration_function()
         except:
             raise exceptions.FailedDryRun(sys.exc_info())
     finally:
         db.rollback_transactions_dry_run()
         db.debug = old_debug
         db.clear_run_data(pending_creates)
         db.dry_run = False
Ejemplo n.º 3
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