Loading django/db/migrations/operations/special.py +1 −1 Original line number Diff line number Diff line Loading @@ -50,7 +50,7 @@ class SeparateDatabaseAndState(Operation): to_state = base_state.clone() for dbop in self.database_operations[:-(pos + 1)]: dbop.state_forwards(app_label, to_state) from_state = base_state.clone() from_state = to_state.clone() database_operation.state_forwards(app_label, from_state) database_operation.database_backwards(app_label, schema_editor, from_state, to_state) Loading docs/releases/1.8.8.txt +3 −0 Original line number Diff line number Diff line Loading @@ -27,3 +27,6 @@ Bugfixes * Restored the ability to use custom formats from ``formats.py`` with ``django.utils.formats.get_format()`` and the ``date`` template filter (:ticket:`25812`). * Fixed a state bug when migrating a ``SeparateDatabaseAndState`` operation backwards (:ticket:`25896`). docs/releases/1.9.1.txt +3 −0 Original line number Diff line number Diff line Loading @@ -16,3 +16,6 @@ Bugfixes (:ticket:`25548`). * Fixed a system check crash with nested ``ArrayField``\s (:ticket:`25867`). * Fixed a state bug when migrating a ``SeparateDatabaseAndState`` operation backwards (:ticket:`25896`). tests/migrations/test_operations.py +76 −0 Original line number Diff line number Diff line Loading @@ -1850,6 +1850,82 @@ class OperationTests(OperationTestBase): self.assertEqual(definition[1], []) self.assertEqual(sorted(definition[2]), ["database_operations", "state_operations"]) def test_separate_database_and_state2(self): """ A complex SeparateDatabaseAndState operation: Multiple operations both for state and database. Verify the state dependencies within each list and that state ops don't affect the database. """ app_label = "test_separatedatabaseandstate2" project_state = self.set_up_test_model(app_label) # Create the operation database_operations = [ migrations.CreateModel( "ILovePonies", [("id", models.AutoField(primary_key=True))], options={"db_table": "iloveponies"}, ), migrations.CreateModel( "ILoveMorePonies", [("id", models.AutoField(primary_key=True))], options={"db_table": "ilovemoreponies"}, ), migrations.DeleteModel("ILoveMorePonies"), migrations.CreateModel( "ILoveEvenMorePonies", [("id", models.AutoField(primary_key=True))], options={"db_table": "iloveevenmoreponies"}, ), ] state_operations = [ migrations.CreateModel( "SomethingElse", [("id", models.AutoField(primary_key=True))], options={"db_table": "somethingelse"}, ), migrations.DeleteModel("SomethingElse"), migrations.CreateModel( "SomethingCompletelyDifferent", [("id", models.AutoField(primary_key=True))], options={"db_table": "somethingcompletelydifferent"}, ), ] operation = migrations.SeparateDatabaseAndState( state_operations=state_operations, database_operations=database_operations, ) # Test the state alteration new_state = project_state.clone() operation.state_forwards(app_label, new_state) def assertModelsAndTables(after_db): # Check that tables and models exist, or don't, as they should: self.assertNotIn((app_label, "somethingelse"), new_state.models) self.assertEqual(len(new_state.models[app_label, "somethingcompletelydifferent"].fields), 1) self.assertNotIn((app_label, "iloveponiesonies"), new_state.models) self.assertNotIn((app_label, "ilovemoreponies"), new_state.models) self.assertNotIn((app_label, "iloveevenmoreponies"), new_state.models) self.assertTableNotExists("somethingelse") self.assertTableNotExists("somethingcompletelydifferent") self.assertTableNotExists("ilovemoreponies") if after_db: self.assertTableExists("iloveponies") self.assertTableExists("iloveevenmoreponies") else: self.assertTableNotExists("iloveponies") self.assertTableNotExists("iloveevenmoreponies") assertModelsAndTables(after_db=False) # Test the database alteration with connection.schema_editor() as editor: operation.database_forwards(app_label, editor, project_state, new_state) assertModelsAndTables(after_db=True) # And test reversal self.assertTrue(operation.reversible) with connection.schema_editor() as editor: operation.database_backwards(app_label, editor, new_state, project_state) assertModelsAndTables(after_db=False) class SwappableOperationTests(OperationTestBase): """ Loading Loading
django/db/migrations/operations/special.py +1 −1 Original line number Diff line number Diff line Loading @@ -50,7 +50,7 @@ class SeparateDatabaseAndState(Operation): to_state = base_state.clone() for dbop in self.database_operations[:-(pos + 1)]: dbop.state_forwards(app_label, to_state) from_state = base_state.clone() from_state = to_state.clone() database_operation.state_forwards(app_label, from_state) database_operation.database_backwards(app_label, schema_editor, from_state, to_state) Loading
docs/releases/1.8.8.txt +3 −0 Original line number Diff line number Diff line Loading @@ -27,3 +27,6 @@ Bugfixes * Restored the ability to use custom formats from ``formats.py`` with ``django.utils.formats.get_format()`` and the ``date`` template filter (:ticket:`25812`). * Fixed a state bug when migrating a ``SeparateDatabaseAndState`` operation backwards (:ticket:`25896`).
docs/releases/1.9.1.txt +3 −0 Original line number Diff line number Diff line Loading @@ -16,3 +16,6 @@ Bugfixes (:ticket:`25548`). * Fixed a system check crash with nested ``ArrayField``\s (:ticket:`25867`). * Fixed a state bug when migrating a ``SeparateDatabaseAndState`` operation backwards (:ticket:`25896`).
tests/migrations/test_operations.py +76 −0 Original line number Diff line number Diff line Loading @@ -1850,6 +1850,82 @@ class OperationTests(OperationTestBase): self.assertEqual(definition[1], []) self.assertEqual(sorted(definition[2]), ["database_operations", "state_operations"]) def test_separate_database_and_state2(self): """ A complex SeparateDatabaseAndState operation: Multiple operations both for state and database. Verify the state dependencies within each list and that state ops don't affect the database. """ app_label = "test_separatedatabaseandstate2" project_state = self.set_up_test_model(app_label) # Create the operation database_operations = [ migrations.CreateModel( "ILovePonies", [("id", models.AutoField(primary_key=True))], options={"db_table": "iloveponies"}, ), migrations.CreateModel( "ILoveMorePonies", [("id", models.AutoField(primary_key=True))], options={"db_table": "ilovemoreponies"}, ), migrations.DeleteModel("ILoveMorePonies"), migrations.CreateModel( "ILoveEvenMorePonies", [("id", models.AutoField(primary_key=True))], options={"db_table": "iloveevenmoreponies"}, ), ] state_operations = [ migrations.CreateModel( "SomethingElse", [("id", models.AutoField(primary_key=True))], options={"db_table": "somethingelse"}, ), migrations.DeleteModel("SomethingElse"), migrations.CreateModel( "SomethingCompletelyDifferent", [("id", models.AutoField(primary_key=True))], options={"db_table": "somethingcompletelydifferent"}, ), ] operation = migrations.SeparateDatabaseAndState( state_operations=state_operations, database_operations=database_operations, ) # Test the state alteration new_state = project_state.clone() operation.state_forwards(app_label, new_state) def assertModelsAndTables(after_db): # Check that tables and models exist, or don't, as they should: self.assertNotIn((app_label, "somethingelse"), new_state.models) self.assertEqual(len(new_state.models[app_label, "somethingcompletelydifferent"].fields), 1) self.assertNotIn((app_label, "iloveponiesonies"), new_state.models) self.assertNotIn((app_label, "ilovemoreponies"), new_state.models) self.assertNotIn((app_label, "iloveevenmoreponies"), new_state.models) self.assertTableNotExists("somethingelse") self.assertTableNotExists("somethingcompletelydifferent") self.assertTableNotExists("ilovemoreponies") if after_db: self.assertTableExists("iloveponies") self.assertTableExists("iloveevenmoreponies") else: self.assertTableNotExists("iloveponies") self.assertTableNotExists("iloveevenmoreponies") assertModelsAndTables(after_db=False) # Test the database alteration with connection.schema_editor() as editor: operation.database_forwards(app_label, editor, project_state, new_state) assertModelsAndTables(after_db=True) # And test reversal self.assertTrue(operation.reversible) with connection.schema_editor() as editor: operation.database_backwards(app_label, editor, new_state, project_state) assertModelsAndTables(after_db=False) class SwappableOperationTests(OperationTestBase): """ Loading