Project

General

Profile

0001-add-list_new_initial_migrations-command-5781.patch

Thomas Noël, 22 October 2014 11:04 AM

Download (4.32 KB)

View differences:

Subject: [PATCH] add list_new_initial_migrations command (#5781)

list all applications already installed, but with new 0001_initial
migration (south).

With this command, migration workflow is :
* syncdb
* for each app listed by list_new_initial_migrations :
      migrate --fake <app> 0001
* migrate
 entrouvert/djommon/management/__init__.py          |  0
 entrouvert/djommon/management/commands/__init__.py |  0
 .../commands/list_new_initial_migrations.py        | 62 ++++++++++++++++++++++
 3 files changed, 62 insertions(+)
 create mode 100644 entrouvert/djommon/management/__init__.py
 create mode 100644 entrouvert/djommon/management/commands/__init__.py
 create mode 100644 entrouvert/djommon/management/commands/list_new_initial_migrations.py
entrouvert/djommon/management/commands/list_new_initial_migrations.py
1
from django.core.management.base import NoArgsCommand
2
from django.db import connections, router, models
3

  
4
from south.models import MigrationHistory
5
from django.core.management.commands import syncdb as django_syncdb
6

  
7

  
8
class Command(NoArgsCommand):
9
    option_list = django_syncdb.Command.option_list
10
    help = '''list apps with new initial migrations (for "migrate --fake <app> 0001")'''
11

  
12
    def handle_noargs(self, *args, **options):
13

  
14
        # detect installed models
15
        # (code borrowed from django syncdb command)
16
        db = options.get('database')
17
        connection = connections[db]
18
        cursor = connection.cursor()
19
        tables = connection.introspection.table_names()
20
        def model_in_database(model):
21
            opts = model._meta
22
            converter = connection.introspection.table_name_converter
23
            return (converter(opts.db_table) in tables) or \
24
                (opts.auto_created and converter(opts.auto_created._meta.db_table) in tables)
25

  
26
        # list all applications with south migration
27
        # (code borrowed from south migrate command)
28
        from south import migration
29
        apps = list(migration.all_migrations())
30
        applied_migrations = MigrationHistory.objects.filter(app_name__in=[app.app_label() for app in apps])
31
        applied_migrations_lookup = dict(('%s.%s' % (mi.app_name, mi.migration), mi) for mi in applied_migrations)
32

  
33
        apps_with_new_initial_migrations = []
34
        for app in apps:
35
            # for each app with migrations, list already applied migrations
36
            applied_migrations = []
37
            for migration in app:
38
                full_name = migration.app_label() + "." + migration.name()
39
                if full_name in applied_migrations_lookup:
40
                    applied_migration = applied_migrations_lookup[full_name]
41
                    if applied_migration.applied:
42
                        applied_migrations.append(migration.name())
43
            # try all models in database, if there none, the application is new
44
            # (because south syncdb does not create any tables)
45
            new = True
46
            for m in models.get_models(app.get_application().models):
47
                if model_in_database(m):
48
                    new = False
49
                    break
50
            if new:
51
                status = 'application-is-new'
52
            elif not applied_migrations:
53
                status = 'migration-is-new'
54
            else:
55
                status = 'normal'
56
            if status == 'migration-is-new':
57
                # The app was installed without migrations, we suppose
58
                # it is the first version 0001.
59
                apps_with_new_initial_migrations.append(app.app_label())
60

  
61
        if apps_with_new_initial_migrations:
62
            print ' '.join(apps_with_new_initial_migrations)
0
-