Commit 72729f84 authored by Andrzej Pragacz's avatar Andrzej Pragacz Committed by Tim Graham
Browse files

Fixed #23794 -- Fixed migrations crash when removing a field that's part of index/unique_together.

parent f957e2b0
Loading
Loading
Loading
Loading
+5 −11
Original line number Diff line number Diff line
@@ -366,16 +366,10 @@ class MigrationAutodetector(object):
            )
        # Field is removed and part of an index/unique_together
        elif dependency[2] is not None and dependency[3] == "foo_together_change":
            if operation.name.lower() == dependency[1].lower():
            return (
                    (
                        isinstance(operation, operations.AlterUniqueTogether) and
                        any(dependency[2] not in t for t in operation.unique_together)
                    ) or
                    (
                        isinstance(operation, operations.AlterIndexTogether) and
                        any(dependency[2] not in t for t in operation.index_together)
                    )
                isinstance(operation, (operations.AlterUniqueTogether,
                                       operations.AlterIndexTogether)) and
                operation.name.lower() == dependency[1].lower()
            )
        # Unknown dependency. Raise an error.
        else:
+3 −0
Original line number Diff line number Diff line
@@ -74,3 +74,6 @@ Bugfixes

* Fixed a rare query error when using deeply nested subqueries
  (:ticket:`23605`).

* Fixed a crash in migrations when deleting a field that is part of a
  ``index/unique_together`` constraint (:ticket:`23794`).
+16 −0
Original line number Diff line number Diff line
@@ -908,6 +908,22 @@ class AutodetectorTests(TestCase):
        self.assertOperationAttributes(changes, "otherapp", 0, 0, name="book", unique_together=set())
        self.assertOperationAttributes(changes, "otherapp", 0, 1, name="book", index_together=set())

    def test_foo_together_remove_fk(self):
        """Tests unique_together and field removal detection & ordering"""
        # Make state
        before = self.make_project_state([self.author_empty, self.book_foo_together])
        after = self.make_project_state([self.author_empty, self.book_with_no_author])
        autodetector = MigrationAutodetector(before, after)
        changes = autodetector._detect_changes()
        # Right number/type of migrations?
        self.assertNumberMigrations(changes, "otherapp", 1)
        self.assertOperationTypes(changes, "otherapp", 0, [
            "AlterUniqueTogether", "AlterIndexTogether", "RemoveField"
        ])
        self.assertOperationAttributes(changes, "otherapp", 0, 0, name="book", unique_together=set())
        self.assertOperationAttributes(changes, "otherapp", 0, 1, name="book", index_together=set())
        self.assertOperationAttributes(changes, "otherapp", 0, 2, model_name="book", name="author")

    def test_foo_together_no_changes(self):
        """
        Tests that index/unique_together doesn't generate a migration if no