#24895: Migration loader fails to load pair of squashed apps when dependent
app's
squashed migrations are partially applied
--------------------------------------+------------------------
Reporter: carljm | Owner: nobody
Type: Bug | Status: new
Component: Migrations | Version: 1.8
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
--------------------------------------+------------------------
Consider the following set of migrations (taken directly from the test
suite; for clarity I removed the repetitive `_auto` suffix from the
migration names, and renamed the apps `A` and `B` instead of `app1` and
`app2`):
app `A`: `1` -> `2` -> `3` -> `4`
app `B`: `1` -> `2`
Where `A.3` has a dependency on `B.2`, and there also exist two squashed
migrations `A.2_squashed_3` and `B.1_squashed_2`.
If `A.2` and `A.3` are both applied or unapplied (that is, their
replacement by `A.2_squashed_3` is allowed to take effect), this migration
set will load fine.
But if `A.2` is applied and `A.3` is not, this migration set will fail to
load with "django.db.migrations.exceptions.NodeNotFoundError: Migration
A.3 dependencies reference nonexistent parent node ('B', '2')".
When the loader iterates over all "replacing" migrations, it finds
`B.1_squashed_2`. Then it looks at each migration replaced by
`B.1_squashed_2`, and one of those is `B.2`. It checks what migrations
depend on `B.2`, so it can replace that dependency with a dependency on
`B.1_squashed_2`. It finds that `A.3` depends on `B.2`. So far so good.
But at this point, before replacing `A.3`'s dependency on `B.2` with a
dependency on `B.1_squashed_2`, it first checks whether `A.3` is itself
replaced by anything. If so, it tries to update the dependencies of the
replacing migration (that is `A.2_squashed_3`) and doesn't bother to
update the dependencies of `A.3` itself. But it fails to check whether,
given the already-applied migrations, `A.2_squashed_3` will _actually_ be
allowed to replace `A.2` and `A.3` -- it just assumes the replacement will
occur. And in the situation where the replacement doesn't occur (because
`A.2` is applied and `A.3` is not), the dependency of `A.3` on `B.2` is
never updated to account for the replacement of `B.2` with
`B.1_squashed_2`, and thus there is a dependency error.
I believe this fix should be backported to the 1.8.x branch, since it is a
crashing bug.
--
Ticket URL: <https://code.djangoproject.com/ticket/24895>
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 post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/049.7c1cde4a19e08fd9eddae8af9eeb930f%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.