From 99640e24b4c42a9f9b1e02d54aec72c13008276d Mon Sep 17 00:00:00 2001 From: manav014 Date: Wed, 10 Mar 2021 19:04:44 +0530 Subject: [PATCH] Fixed #31516 -- Improved naming of migrations with multiple operations. 52 gives 60 in total (52 + 5 + 3). Co-authored-by: Adam Johnson --- django/db/migrations/migration.py | 24 +++++++------- tests/migrations/test_autodetector.py | 45 ++++++++++++++++++++++++++- 2 files changed, 57 insertions(+), 12 deletions(-) diff --git a/django/db/migrations/migration.py b/django/db/migrations/migration.py index 9d2952b1a8..5ee0ae5191 100644 --- a/django/db/migrations/migration.py +++ b/django/db/migrations/migration.py @@ -1,4 +1,3 @@ -from django.db.migrations import operations from django.db.migrations.utils import get_migration_name_timestamp from django.db.transaction import atomic @@ -186,16 +185,19 @@ class Migration: if self.initial: return 'initial' - name = None - if len(self.operations) == 1: - name = self.operations[0].migration_name_fragment - elif ( - len(self.operations) > 1 and - all(isinstance(o, operations.CreateModel) for o in self.operations) - ): - name = '_'.join(sorted(o.migration_name_fragment for o in self.operations)) - if name is None: - name = 'auto_%s' % get_migration_name_timestamp() + raw_fragments = [op.migration_name_fragment for op in self.operations] + fragments = [name for name in raw_fragments if name] + + if not fragments or len(fragments) != len(self.operations): + return 'auto_%s' % get_migration_name_timestamp() + + name = fragments[0] + for fragment in fragments[1:]: + new_name = f'{name}_{fragment}' + if len(new_name) > 52: + name = f'{name}_and_more' + break + name = new_name return name diff --git a/tests/migrations/test_autodetector.py b/tests/migrations/test_autodetector.py index 859f32baaf..707b84dab3 100644 --- a/tests/migrations/test_autodetector.py +++ b/tests/migrations/test_autodetector.py @@ -2661,6 +2661,23 @@ class MigrationSuggestNameTests(SimpleTestCase): migration = Migration('0002_initial', 'test_app') self.assertEqual(migration.suggest_name(), 'delete_person') + def test_single_operation_long_name(self): + class Migration(migrations.Migration): + operations = [migrations.CreateModel('A' * 53, fields=[])] + + migration = Migration('some_migration', 'test_app') + self.assertEqual(migration.suggest_name(), 'a' * 53) + + def test_two_operations(self): + class Migration(migrations.Migration): + operations = [ + migrations.CreateModel('Person', fields=[]), + migrations.DeleteModel('Animal'), + ] + + migration = Migration('some_migration', 'test_app') + self.assertEqual(migration.suggest_name(), 'person_delete_animal') + def test_two_create_models(self): class Migration(migrations.Migration): operations = [ @@ -2669,7 +2686,7 @@ class MigrationSuggestNameTests(SimpleTestCase): ] migration = Migration('0001_initial', 'test_app') - self.assertEqual(migration.suggest_name(), 'animal_person') + self.assertEqual(migration.suggest_name(), 'person_animal') def test_two_create_models_with_initial_true(self): class Migration(migrations.Migration): @@ -2682,6 +2699,32 @@ class MigrationSuggestNameTests(SimpleTestCase): migration = Migration('0001_initial', 'test_app') self.assertEqual(migration.suggest_name(), 'initial') + def test_many_operations_suffix(self): + class Migration(migrations.Migration): + operations = [ + migrations.CreateModel('Person1', fields=[]), + migrations.CreateModel('Person2', fields=[]), + migrations.CreateModel('Person3', fields=[]), + migrations.DeleteModel('Person4'), + migrations.DeleteModel('Person5'), + ] + + migration = Migration('some_migration', 'test_app') + self.assertEqual( + migration.suggest_name(), + 'person1_person2_person3_delete_person4_and_more', + ) + + def test_operation_with_no_suggested_name(self): + class Migration(migrations.Migration): + operations = [ + migrations.CreateModel('Person', fields=[]), + migrations.RunSQL('SELECT 1 FROM person;'), + ] + + migration = Migration('some_migration', 'test_app') + self.assertIs(migration.suggest_name().startswith('auto_'), True) + def test_none_name(self): class Migration(migrations.Migration): operations = [migrations.RunSQL('SELECT 1 FROM person;')]