diff --git a/django/core/management/commands/squashmigrations.py b/django/core/management/commands/squashmigrations.py index ece5acb69e..2b3aa412ca 100644 --- a/django/core/management/commands/squashmigrations.py +++ b/django/core/management/commands/squashmigrations.py @@ -24,7 +24,7 @@ class Command(BaseCommand): usage_str = "Usage: ./manage.py squashmigrations app migration_name" args = "app_label migration_name" - def handle(self, app_label=None, migration_name=None, **options): + def handle(self, app_label=None, migration_name=None, no_optimize=None, **options): self.verbosity = int(options.get('verbosity')) self.interactive = options.get('interactive') @@ -87,17 +87,25 @@ class Command(BaseCommand): elif dependency[0] != smigration.app_label: dependencies.add(dependency) - if self.verbosity > 0: - self.stdout.write(self.style.MIGRATE_HEADING("Optimizing...")) + if no_optimize: + if self.verbosity > 0: + self.stdout.write(self.style.MIGRATE_HEADING("(Skipping optimization.)")) + new_operations = operations + else: + if self.verbosity > 0: + self.stdout.write(self.style.MIGRATE_HEADING("Optimizing...")) - optimizer = MigrationOptimizer() - new_operations = optimizer.optimize(operations, migration.app_label) + optimizer = MigrationOptimizer() + new_operations = optimizer.optimize(operations, migration.app_label) - if self.verbosity > 0: - if len(new_operations) == len(operations): - self.stdout.write(" No optimizations possible.") - else: - self.stdout.write(" Optimized from %s operations to %s operations." % (len(operations), len(new_operations))) + if self.verbosity > 0: + if len(new_operations) == len(operations): + self.stdout.write(" No optimizations possible.") + else: + self.stdout.write( + " Optimized from %s operations to %s operations." % + (len(operations), len(new_operations)) + ) # Work out the value of replaces (any squashed ones we're re-squashing) # need to feed their replaces into ours diff --git a/docs/releases/1.7.2.txt b/docs/releases/1.7.2.txt index 8420b5b303..0fe97a3225 100644 --- a/docs/releases/1.7.2.txt +++ b/docs/releases/1.7.2.txt @@ -62,3 +62,6 @@ Bugfixes * Fixed a migration crash when a field is renamed that is part of an ``index_together`` (:ticket:`23859`). + +* Fixed :djadmin:`squashmigrations` to respect the ``--no-optimize`` parameter + (:ticket:`23799`). diff --git a/tests/migrations/test_commands.py b/tests/migrations/test_commands.py index 00b7f65ab8..a889ec8037 100644 --- a/tests/migrations/test_commands.py +++ b/tests/migrations/test_commands.py @@ -546,3 +546,45 @@ class MakeMigrationsTests(MigrationTestBase): questioner.input = old_input if os.path.exists(merge_file): os.remove(merge_file) + + +class SquashMigrationsTest(MigrationTestBase): + """ + Tests running the squashmigrations command. + """ + + path = "migrations/test_migrations/0001_squashed_0002_second.py" + + def tearDown(self): + if os.path.exists(self.path): + os.remove(self.path) + + @override_system_checks([]) + @override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations"}) + def test_squashmigrations_squashes(self): + """ + Tests that squashmigrations squashes migrations. + """ + call_command("squashmigrations", "migrations", "0002", interactive=False, verbosity=0) + self.assertTrue(os.path.exists(self.path)) + + @override_system_checks([]) + @override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations"}) + def test_squashmigrations_optimizes(self): + """ + Tests that squashmigrations optimizes operations. + """ + out = six.StringIO() + call_command("squashmigrations", "migrations", "0002", interactive=False, verbosity=1, stdout=out) + self.assertIn("Optimized from 7 operations to 5 operations.", out.getvalue()) + + @override_system_checks([]) + @override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations"}) + def test_ticket_23799_squashmigrations_no_optimize(self): + """ + Makes sure that squashmigrations --no-optimize really doesn't optimize operations. + """ + out = six.StringIO() + call_command("squashmigrations", "migrations", "0002", + interactive=False, verbosity=1, no_optimize=True, stdout=out) + self.assertIn("Skipping optimization", out.getvalue())