Search code examples
djangodata-migrationdjango-south

Programmatically check whether there are django south migrations that need to be deployed


My deployment strategy looks like this (using Fabric):

  1. create a new virtualenv
  2. deploy new code in new virtualenv
  3. show a maintenance page
  4. copy the current db to new db
  5. migrate new db
  6. point new code to new db
  7. symlink current virtualenv to new venv
  8. restart services
  9. remove maintenance page

I want to iterate fast. Now, most of the code changes do not contain migrations. Also, the db is growing, so there is much overhead created by copying the database everytime I deploy a (mostly small) change. To avoid copying the database I want to check whether there are migrations that need to be deployed (prior to step 4). If there are no migrations, I can go straight from step 2 to step 7. If there are, I will follow all the steps. For this, I need to check programmatically whether there are migrations that need to be deployed. How can I do this?


Solution

  • In step 2 while deploying the new code, you could deploy a script which when run on the server will detect if there are new migrations.

    Example code is as follows:

    # copied mostly from south.management.commands.migrate
    from south import migration
    from south.models import MigrationHistory
    
    apps  = list(migration.all_migrations())
    
    applied_migrations = MigrationHistory.objects.filter(app_name__in=[app.app_label() for app in apps])
    applied_migrations = ['%s.%s' % (mi.app_name,mi.migration) for mi in applied_migrations]
    
    num_new_migrations = 0
    for app in apps:
        for migration in app:
            if migration.app_label() + "." + migration.name() not in applied_migrations:
                num_new_migrations = num_new_migrations + 1
    
    return num_new_migrations
    

    If you wrap the above code up in a script, your fabric deployment script can use the run operation to get the number of new migrations.

    If this returns zero, then you can skip the steps associated with copying the database.