Commit 7eabd222 authored by Dave Hall's avatar Dave Hall Committed by Tim Graham
Browse files

[1.7.x] Fixed #22918 -- Fixed SeparateDatabaseAndState crash

Backport of e03b7940 from master
parent a7ac5f01
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@ class SeparateDatabaseAndState(Operation):
        for database_operation in self.database_operations:
            to_state = from_state.clone()
            database_operation.state_forwards(app_label, to_state)
            database_operation.database_forwards(self, app_label, schema_editor, from_state, to_state)
            database_operation.database_forwards(app_label, schema_editor, from_state, to_state)
            from_state = to_state

    def database_backwards(self, app_label, schema_editor, from_state, to_state):
@@ -36,7 +36,7 @@ class SeparateDatabaseAndState(Operation):
                dbop.state_forwards(app_label, to_state)
            from_state = base_state.clone()
            database_operation.state_forwards(app_label, from_state)
            database_operation.database_backwards(self, app_label, schema_editor, from_state, to_state)
            database_operation.database_backwards(app_label, schema_editor, from_state, to_state)

    def describe(self):
        return "Custom state/database change combination"
+33 −0
Original line number Diff line number Diff line
@@ -1278,6 +1278,39 @@ class OperationTests(OperationTestBase):
                    non_atomic_migration.apply(project_state, editor)
            self.assertEqual(project_state.render().get_model("test_runpythonatomic", "Pony").objects.count(), 1)

    @unittest.skipIf(sqlparse is None and connection.features.requires_sqlparse_for_splitting, "Missing sqlparse")
    def test_separate_database_and_state(self):
        """
        Tests the SeparateDatabaseAndState operation.
        """
        project_state = self.set_up_test_model("test_separatedatabaseandstate")
        # Create the operation
        database_operation = migrations.RunSQL(
            "CREATE TABLE i_love_ponies (id int, special_thing int);",
            "DROP TABLE i_love_ponies;"
        )
        state_operation = migrations.CreateModel("SomethingElse", [("id", models.AutoField(primary_key=True))])
        operation = migrations.SeparateDatabaseAndState(
            state_operations=[state_operation],
            database_operations=[database_operation]
        )
        self.assertEqual(operation.describe(), "Custom state/database change combination")
        # Test the state alteration
        new_state = project_state.clone()
        operation.state_forwards("test_separatedatabaseandstate", new_state)
        self.assertEqual(len(new_state.models["test_separatedatabaseandstate", "somethingelse"].fields), 1)
        # Make sure there's no table
        self.assertTableNotExists("i_love_ponies")
        # Test the database alteration
        with connection.schema_editor() as editor:
            operation.database_forwards("test_separatedatabaseandstate", editor, project_state, new_state)
        self.assertTableExists("i_love_ponies")
        # And test reversal
        self.assertTrue(operation.reversible)
        with connection.schema_editor() as editor:
            operation.database_backwards("test_separatedatabaseandstate", editor, new_state, project_state)
        self.assertTableNotExists("i_love_ponies")


class MigrateNothingRouter(object):
    """