Переглянути джерело

Fixed #22918 -- Fixed SeparateDatabaseAndState crash

Dave Hall 10 роки тому
батько
коміт
e03b7940e5

+ 2 - 2
django/db/migrations/operations/special.py

@@ -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
tests/migrations/test_operations.py

@@ -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):
     """