Add --list option to migrate command
This commit is contained in:
parent
a91799a30c
commit
9f6e6009a4
|
@ -1,3 +1,5 @@
|
||||||
|
# encoding: utf8
|
||||||
|
from __future__ import unicode_literals
|
||||||
from optparse import make_option
|
from optparse import make_option
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from importlib import import_module
|
from importlib import import_module
|
||||||
|
@ -11,7 +13,7 @@ from django.core.management.color import no_style
|
||||||
from django.core.management.sql import custom_sql_for_model, emit_post_migrate_signal, emit_pre_migrate_signal
|
from django.core.management.sql import custom_sql_for_model, emit_post_migrate_signal, emit_pre_migrate_signal
|
||||||
from django.db import connections, router, transaction, models, DEFAULT_DB_ALIAS
|
from django.db import connections, router, transaction, models, DEFAULT_DB_ALIAS
|
||||||
from django.db.migrations.executor import MigrationExecutor
|
from django.db.migrations.executor import MigrationExecutor
|
||||||
from django.db.migrations.loader import AmbiguityError
|
from django.db.migrations.loader import MigrationLoader, AmbiguityError
|
||||||
from django.utils.module_loading import module_has_submodule
|
from django.utils.module_loading import module_has_submodule
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,6 +28,8 @@ class Command(BaseCommand):
|
||||||
'Defaults to the "default" database.'),
|
'Defaults to the "default" database.'),
|
||||||
make_option('--fake', action='store_true', dest='fake', default=False,
|
make_option('--fake', action='store_true', dest='fake', default=False,
|
||||||
help='Mark migrations as run without actually running them'),
|
help='Mark migrations as run without actually running them'),
|
||||||
|
make_option('--list', action='store_true', dest='list', default=False,
|
||||||
|
help='Show a list of all known migrations and which are applied'),
|
||||||
)
|
)
|
||||||
|
|
||||||
help = "Updates database schema. Manages both apps with migrations and those without."
|
help = "Updates database schema. Manages both apps with migrations and those without."
|
||||||
|
@ -48,6 +52,10 @@ class Command(BaseCommand):
|
||||||
db = options.get('database')
|
db = options.get('database')
|
||||||
connection = connections[db]
|
connection = connections[db]
|
||||||
|
|
||||||
|
# If they asked for a migration listing, quit main execution flow and show it
|
||||||
|
if options.get("list", False):
|
||||||
|
return self.show_migration_list(connection, args)
|
||||||
|
|
||||||
# Work out which apps have migrations and which do not
|
# Work out which apps have migrations and which do not
|
||||||
executor = MigrationExecutor(connection, self.migration_progress_callback)
|
executor = MigrationExecutor(connection, self.migration_progress_callback)
|
||||||
|
|
||||||
|
@ -243,3 +251,39 @@ class Command(BaseCommand):
|
||||||
call_command('loaddata', 'initial_data', verbosity=self.verbosity, database=connection.alias, skip_validation=True)
|
call_command('loaddata', 'initial_data', verbosity=self.verbosity, database=connection.alias, skip_validation=True)
|
||||||
|
|
||||||
return created_models
|
return created_models
|
||||||
|
|
||||||
|
def show_migration_list(self, connection, apps=None):
|
||||||
|
"""
|
||||||
|
Shows a list of all migrations on the system, or only those of
|
||||||
|
some named apps.
|
||||||
|
"""
|
||||||
|
# Load migrations from disk/DB
|
||||||
|
loader = MigrationLoader(connection)
|
||||||
|
graph = loader.graph
|
||||||
|
# If we were passed a list of apps, validate it
|
||||||
|
if apps:
|
||||||
|
invalid_apps = []
|
||||||
|
for app in apps:
|
||||||
|
if app_label not in loader.migrated_apps:
|
||||||
|
invalid_apps.append(app)
|
||||||
|
if invalid_apps:
|
||||||
|
raise CommandError("No migrations present for: %s" % (", ".join(invalid_apps)))
|
||||||
|
# Otherwise, show all apps in alphabetic order
|
||||||
|
else:
|
||||||
|
apps = sorted(loader.migrated_apps)
|
||||||
|
# For each app, print its migrations in order from oldest (roots) to
|
||||||
|
# newest (leaves).
|
||||||
|
for app in apps:
|
||||||
|
self.stdout.write(app, self.style.MIGRATE_LABEL)
|
||||||
|
shown = set()
|
||||||
|
for node in graph.leaf_nodes(app):
|
||||||
|
for plan_node in graph.forwards_plan(node):
|
||||||
|
if plan_node not in shown and plan_node[0] == app:
|
||||||
|
if plan_node in loader.applied_migrations:
|
||||||
|
self.stdout.write(" [X] %s" % plan_node[1])
|
||||||
|
else:
|
||||||
|
self.stdout.write(" [ ] %s" % plan_node[1])
|
||||||
|
shown.add(plan_node)
|
||||||
|
# If we didn't print anything, then a small message
|
||||||
|
if not shown:
|
||||||
|
self.stdout.write(" (no migrations)", self.style.MIGRATE_FAILURE)
|
||||||
|
|
|
@ -74,7 +74,7 @@ class MigrationGraph(object):
|
||||||
roots.add(node)
|
roots.add(node)
|
||||||
return roots
|
return roots
|
||||||
|
|
||||||
def leaf_nodes(self):
|
def leaf_nodes(self, app=None):
|
||||||
"""
|
"""
|
||||||
Returns all leaf nodes - that is, nodes with no dependents in their app.
|
Returns all leaf nodes - that is, nodes with no dependents in their app.
|
||||||
These are the "most current" version of an app's schema.
|
These are the "most current" version of an app's schema.
|
||||||
|
@ -84,7 +84,7 @@ class MigrationGraph(object):
|
||||||
"""
|
"""
|
||||||
leaves = set()
|
leaves = set()
|
||||||
for node in self.nodes:
|
for node in self.nodes:
|
||||||
if not any(key[0] == node[0] for key in self.dependents.get(node, set())):
|
if not any(key[0] == node[0] for key in self.dependents.get(node, set())) and (not app or app == node[0]):
|
||||||
leaves.add(node)
|
leaves.add(node)
|
||||||
return leaves
|
return leaves
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue