#35595: Generated migration for removing related models can't migrate backwards
-----------------------------------+------------------------------------
     Reporter:  Timothy Schilling  |                    Owner:  wookkl
         Type:  Bug                |                   Status:  assigned
    Component:  Migrations         |                  Version:  5.0
     Severity:  Normal             |               Resolution:
     Keywords:                     |             Triage Stage:  Accepted
    Has patch:  1                  |      Needs documentation:  0
  Needs tests:  0                  |  Patch needs improvement:  1
Easy pickings:  0                  |                    UI/UX:  0
-----------------------------------+------------------------------------
Changes (by Simon Charette):

 * needs_better_patch:  0 => 1

Comment:

 I think the actual issue is less about the migration `sqlmigrate` crashing
 but more about the auto-detector generating an invalid migration.

 The resulting migration operations of removing all models should include a
 `RemoveIndex` operation that precedes the `RemoveField`

 {{{#!python
 operations = [
     migrations.RemoveIndex(
         model_name="dog",
         name="animal",
     ),
     migrations.RemoveField(
         model_name="dog",
         name="animal",
     ),
     migrations.DeleteModel(
         name="Animal",
     ),
     migrations.DeleteModel(
         name="Dog",
     ),
 ]
 }}}

 This is a test that should pass

 {{{#!diff
 diff --git a/tests/migrations/test_autodetector.py
 b/tests/migrations/test_autodetector.py
 index ac725d317e..30085e5c9b 100644
 --- a/tests/migrations/test_autodetector.py
 +++ b/tests/migrations/test_autodetector.py
 @@ -2798,6 +2798,36 @@ def test_remove_indexes(self):
              changes, "otherapp", 0, 0, model_name="book",
 name="book_title_author_idx"
          )

 +    def test_remove_field_and_index(self):
 +        before_state = [
 +            ModelState("testapp", "Animal", []),
 +            ModelState(
 +                "testapp",
 +                "Dog",
 +                fields=[
 +                    ("name", models.CharField(max_length=100)),
 +                    (
 +                        "animal",
 +                        models.ForeignKey("testapp.Animal",
 on_delete=models.CASCADE),
 +                    ),
 +                ],
 +                options={
 +                    "indexes": [
 +                        models.Index(fields=("animal", "name"),
 name="animal_name_idx")
 +                    ]
 +                },
 +            ),
 +        ]
 +        changes = self.get_changes(before_state, [])
 +        # Right number/type of migrations?
 +        self.assertNumberMigrations(changes, "testapp", 1)
 +        self.assertOperationTypes(
 +            changes,
 +            "testapp",
 +            0,
 +            ["RemoveIndex", "RemoveField", "DeleteModel", "DeleteModel"],
 +        )
 +
      def test_rename_indexes(self):
          book_renamed_indexes = ModelState(
              "otherapp",
 }}}

 and the likely culprit lies in
 `MigrationAutodetector.generate_deleted_models` which should add a
 `RemoveIndex` operations for each index like we do for `unique_together`
 being turned into `None`. We'll likely need to add a new
 `OperationDependency.Type.REMOVE_INDEX_OR_CONSTRAINT` so `RemoveField`
 have their `dependencies` are always sorted after the newly introduced
 `RemoveIndex`.

 Small demonstration of how
 [https://github.com/django/django/compare/main...charettes:django:ticket-35595
 this can be done].

 FWIW the same issue will happens for `constraints` so we should add a test
 for that as well.
-- 
Ticket URL: <https://code.djangoproject.com/ticket/35595#comment:5>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion visit 
https://groups.google.com/d/msgid/django-updates/010701961668d23f-3c6a91a0-0065-4e05-869a-7e73a5e0ca62-000000%40eu-central-1.amazonses.com.

Reply via email to