Carmel Avnon avatar Carmel Avnon committed d8c394f

Fix for #509: in schemamigration and datamigration commands, automatically add a dependency on the last applied migration if that migration was from a different app.

Comments (0)

Files changed (2)

south/management/commands/datamigration.py

 from south.migration import Migrations
 from south.exceptions import NoMigrations
 from south.creator import freezer
+from south.models import MigrationHistory
 
 class Command(BaseCommand):
     option_list = BaseCommand.option_list + (
         # Work out which apps to freeze
         apps_to_freeze = self.calc_frozen_apps(migrations, freeze_list)
         
+        # Add automatic dependencies. 
+        dependencies = []
+        try: 
+            last_applied_migration = MigrationHistory.objects.latest('applied')
+        except MigrationHistory.DoesNotExist(): 
+            last_applied_migration = None 
+            
+        # If last migration app differs from this app, add dependency on last migration. 
+        if last_applied_migration.app_name !=  app: 
+            dependencies.append('("%(app_name)s", "%(migration)s"),' % { 
+                                                'app_name': last_applied_migration.app_name, 
+                                                'migration': last_applied_migration.migration
+                                                })
+        dependencies_str = None 
+        if len(dependencies) > 0: 
+            dependencies_str = DEPENDENCIES_TEMPLATE % {
+                "dependencies": "\n".join(dependencies or [""]), 
+            } 
+            
         # So, what's in this file, then?
         file_contents = MIGRATION_TEMPLATE % {
+            "dependencies": dependencies_str or "",  
             "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 ""
         }
         print >>sys.stderr, message
         sys.exit(code)
 
+DEPENDENCIES_TEMPLATE = """    depends_on = ( 
+        %(dependencies)s
+    ) 
+"""
 
 MIGRATION_TEMPLATE = """# -*- coding: utf-8 -*-
 import datetime
 from django.db import models
 
 class Migration(DataMigration):
-
+%(dependencies)s
     def forwards(self, orm):
         "Write your forwards methods here."
         # Note: Remember to use orm['appname.ModelName'] rather than "from appname.models..."

south/management/commands/schemamigration.py

 from south.exceptions import NoMigrations
 from south.creator import changes, actions, freezer
 from south.management.commands.datamigration import Command as DataCommand
+from south.models import MigrationHistory
 
 class Command(DataCommand):
     option_list = DataCommand.option_list + (
             # 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()
         # Work out which apps to freeze
         apps_to_freeze = self.calc_frozen_apps(migrations, freeze_list)
         
+        
+        # Add automatic dependencies. 
+        dependencies = []
+        try: 
+            last_applied_migration = MigrationHistory.objects.latest('applied')
+        except MigrationHistory.DoesNotExist(): 
+            last_applied_migration = None 
+            
+        # If last migration app differs from this app, add dependency on last migration. 
+        if last_applied_migration.app_name !=  app: 
+            dependencies.append('("%(app_name)s", "%(migration)s"),' % { 
+                                                'app_name': last_applied_migration.app_name, 
+                                                'migration': last_applied_migration.migration
+                                                })
+        dependencies_str = None 
+        if len(dependencies) > 0: 
+            dependencies_str = DEPENDENCIES_TEMPLATE % {
+                "dependencies": "\n".join(dependencies or [""]), 
+            } 
+            
         # So, what's in this file, then?
         file_contents = MIGRATION_TEMPLATE % {
+            "dependencies": dependencies_str or "",  
             "forwards": "\n".join(forwards_actions or ["        pass"]),
             "backwards": "\n".join(backwards_actions or ["        pass"]),
             "frozen_models":  freezer.freeze_apps_to_string(apps_to_freeze),
             else:
                 print >>sys.stderr, "Created %s. You can now apply this migration with: ./manage.py migrate %s" % (new_filename, app)
 
+DEPENDENCIES_TEMPLATE = """    depends_on = ( 
+        %(dependencies)s
+    ) 
+"""
 
 MIGRATION_TEMPLATE = """# -*- coding: utf-8 -*-
 import datetime
 
 
 class Migration(SchemaMigration):
-
+%(dependencies)s
     def forwards(self, orm):
 %(forwards)s
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.