mirror of
https://github.com/django/django.git
synced 2024-12-22 17:16:24 +00:00
Fixed #31402 -- Added migrate --check option.
Command exits with non-zero status if unapplied migrations exist.
This commit is contained in:
parent
4216225480
commit
d0da2820ca
@ -1,3 +1,4 @@
|
||||
import sys
|
||||
import time
|
||||
from importlib import import_module
|
||||
|
||||
@ -62,6 +63,10 @@ class Command(BaseCommand):
|
||||
'--run-syncdb', action='store_true',
|
||||
help='Creates tables for apps without migrations.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--check', action='store_true', dest='check_unapplied',
|
||||
help='Exits with a non-zero status if unapplied migrations exist.',
|
||||
)
|
||||
|
||||
@no_translations
|
||||
def handle(self, *args, **options):
|
||||
@ -143,6 +148,7 @@ class Command(BaseCommand):
|
||||
targets = executor.loader.graph.leaf_nodes()
|
||||
|
||||
plan = executor.migration_plan(targets)
|
||||
exit_dry = plan and options['check_unapplied']
|
||||
|
||||
if options['plan']:
|
||||
self.stdout.write('Planned operations:', self.style.MIGRATE_LABEL)
|
||||
@ -154,7 +160,11 @@ class Command(BaseCommand):
|
||||
message, is_error = self.describe_operation(operation, backwards)
|
||||
style = self.style.WARNING if is_error else None
|
||||
self.stdout.write(' ' + message, style)
|
||||
if exit_dry:
|
||||
sys.exit(1)
|
||||
return
|
||||
if exit_dry:
|
||||
sys.exit(1)
|
||||
|
||||
# At this point, ignore run_syncdb if there aren't any apps to sync.
|
||||
run_syncdb = options['run_syncdb'] and executor.loader.unmigrated_apps
|
||||
|
@ -865,6 +865,13 @@ with hundreds of models.
|
||||
Suppresses all user prompts. An example prompt is asking about removing stale
|
||||
content types.
|
||||
|
||||
.. django-admin-option:: --check
|
||||
|
||||
.. versionadded:: 3.1
|
||||
|
||||
Makes ``migrate`` exit with a non-zero status when unapplied migrations are
|
||||
detected.
|
||||
|
||||
``runserver``
|
||||
-------------
|
||||
|
||||
|
@ -300,6 +300,9 @@ Management Commands
|
||||
enabled for all configured :setting:`DATABASES` by passing the ``database``
|
||||
tag to the command.
|
||||
|
||||
* The new :option:`migrate --check` option makes the command exit with a
|
||||
non-zero status when unapplied migrations are detected.
|
||||
|
||||
Migrations
|
||||
~~~~~~~~~~
|
||||
|
||||
|
@ -249,6 +249,39 @@ class MigrateTests(MigrationTestBase):
|
||||
with self.assertRaisesMessage(CommandError, "Conflicting migrations detected"):
|
||||
call_command("migrate", "migrations")
|
||||
|
||||
@override_settings(MIGRATION_MODULES={
|
||||
'migrations': 'migrations.test_migrations',
|
||||
})
|
||||
def test_migrate_check(self):
|
||||
with self.assertRaises(SystemExit):
|
||||
call_command('migrate', 'migrations', '0001', check_unapplied=True, verbosity=0)
|
||||
self.assertTableNotExists('migrations_author')
|
||||
self.assertTableNotExists('migrations_tribble')
|
||||
self.assertTableNotExists('migrations_book')
|
||||
|
||||
@override_settings(MIGRATION_MODULES={
|
||||
'migrations': 'migrations.test_migrations_plan',
|
||||
})
|
||||
def test_migrate_check_plan(self):
|
||||
out = io.StringIO()
|
||||
with self.assertRaises(SystemExit):
|
||||
call_command(
|
||||
'migrate',
|
||||
'migrations',
|
||||
'0001',
|
||||
check_unapplied=True,
|
||||
plan=True,
|
||||
stdout=out,
|
||||
no_color=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
'Planned operations:\n'
|
||||
'migrations.0001_initial\n'
|
||||
' Create model Salamander\n'
|
||||
' Raw Python operation -> Grow salamander tail.\n',
|
||||
out.getvalue(),
|
||||
)
|
||||
|
||||
@override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations"})
|
||||
def test_showmigrations_list(self):
|
||||
"""
|
||||
|
Loading…
Reference in New Issue
Block a user