Migrate prompts if you need makemigrations, runserver prompts for migrate

This commit is contained in:
Andrew Godwin 2013-12-04 13:32:46 +00:00
parent abb04f1f3f
commit 1d20e6df95
2 changed files with 25 additions and 1 deletions

View File

@ -14,6 +14,9 @@ from django.core.management.sql import custom_sql_for_model, emit_post_migrate_s
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 MigrationLoader, AmbiguityError from django.db.migrations.loader import MigrationLoader, AmbiguityError
from django.db.migrations.state import ProjectState
from django.db.migrations.autodetector import MigrationAutodetector
from django.db.models.loading import cache
from django.utils.module_loading import module_has_submodule from django.utils.module_loading import module_has_submodule
@ -120,6 +123,15 @@ class Command(BaseCommand):
if not plan: if not plan:
if self.verbosity >= 1: if self.verbosity >= 1:
self.stdout.write(" No migrations needed.") self.stdout.write(" No migrations needed.")
# If there's changes that aren't in migrations yet, tell them how to fix it.
autodetector = MigrationAutodetector(
executor.loader.graph.project_state(),
ProjectState.from_app_cache(cache),
)
changes = autodetector.changes(graph=executor.loader.graph)
if changes:
self.stdout.write(self.style.NOTICE(" Your models have changes that are not yet reflected in a migration, and so won't be applied."))
self.stdout.write(self.style.NOTICE(" Run 'manage.py makemigrations' to make new migrations, and then re-run 'manage.py migrate' to apply them."))
else: else:
executor.migrate(targets, plan, fake=options.get("fake", False)) executor.migrate(targets, plan, fake=options.get("fake", False))

View File

@ -10,6 +10,8 @@ import socket
from django.core.management.base import BaseCommand, CommandError from django.core.management.base import BaseCommand, CommandError
from django.core.servers.basehttp import run, get_internal_wsgi_application from django.core.servers.basehttp import run, get_internal_wsgi_application
from django.db import connections, DEFAULT_DB_ALIAS
from django.db.migrations.executor import MigrationExecutor
from django.utils import autoreload from django.utils import autoreload
from django.utils import six from django.utils import six
@ -99,10 +101,10 @@ class Command(BaseCommand):
self.stdout.write("Validating models...\n\n") self.stdout.write("Validating models...\n\n")
self.validate(display_num_errors=True) self.validate(display_num_errors=True)
self.check_migrations()
now = datetime.now().strftime('%B %d, %Y - %X') now = datetime.now().strftime('%B %d, %Y - %X')
if six.PY2: if six.PY2:
now = now.decode('utf-8') now = now.decode('utf-8')
self.stdout.write(( self.stdout.write((
"%(started_at)s\n" "%(started_at)s\n"
"Django version %(version)s, using settings %(settings)r\n" "Django version %(version)s, using settings %(settings)r\n"
@ -144,6 +146,16 @@ class Command(BaseCommand):
self.stdout.write(shutdown_message) self.stdout.write(shutdown_message)
sys.exit(0) sys.exit(0)
def check_migrations(self):
"""
Checks to see if the set of migrations on disk matches the
migrations in the database. Prints a warning if they don't match.
"""
executor = MigrationExecutor(connections[DEFAULT_DB_ALIAS])
plan = executor.migration_plan(executor.loader.graph.leaf_nodes())
if plan:
self.stdout.write(self.style.NOTICE("\nYou have unapplied migrations; your app may not work properly until they are applied."))
self.stdout.write(self.style.NOTICE("Run 'python manage.py migrate' to apply them.\n"))
# Kept for backward compatibility # Kept for backward compatibility
BaseRunserverCommand = Command BaseRunserverCommand = Command