Changes between Initial Version and Version 3 of Ticket #24628


Ignore:
Timestamp:
Jun 1, 2015, 7:12:22 PM (9 years ago)
Author:
Carl Meyer
Comment:

I just ran into this as well. I think it is definitely a bug and should be fixed in code, not just in documentation.

Legend:

Unmodified
Added
Removed
Modified
  • Ticket #24628

    • Property Triage Stage UnreviewedAccepted
    • Property Version master1.8
    • Property Summary Cannot apply migration that depends on squashed migrationSquash migration is not marked as applied when the migrations it replaces are
  • Ticket #24628 – Description

    initial v3  
     1(I am attempting a shorter and clearer description of this bug, but leaving the original description intact below - carljm).
     2
     3In Django 1.8, consider an app `A` with migrations `1` and `2` and a squashed migration `1_squashed_2` that replaces both `1` and `2`. Consider a deployment of this app which has only `1` applied. When it receives the update including `2` and `1_squashed_2` and is migrated, `2` is marked as applied in the database but `1_squashed_2` is not.
     4
     5This does not immediately appear to be a problem, because as long as migrations `1` and `2` exist and `1_squashed_2` is marked as replacing them, Django automatically considers `1_squashed_2` to be applied (and shows it as such in `showmigrations`). But Django never actually records `1_squashed_2` itself as applied in the database.
     6
     7At some point, once all deployments have migrated through `2`, the idea is that `1` and `2` can be removed, and the `replaces` tag removed from `1_squashed_2`. At this point we have a problem, because now Django considers `1_squashed_2` to not be applied, and tries to apply it again, causing errors because tables already exist, etc. The only solution is to manually `--fake` squashed migrations on all deployments when their `replaces` tag is removed, which is a pain and eliminates much of the convenience of the migration system; `--fake` should not be necessary in the normal course of things.
     8
     9The solution appears simple: anytime a migration is marked as having been applied, Django should check if it is part of a replaced set, and if that replaced set is now fully applied, the replacing migration should also be marked as applied.
     10
     11It may be that this check should be performed by `migrate` even when it hasn't applied any migrations in the current run, as that would help to correct the corruption already caused by this bug in many existing databases, but not yet noticed because the replaced migrations haven't yet been removed. (This correction should probably be mentioned to the user so it doesn't happen silently.)
     12
     13Original report follows:
     14
    115After some time in the chat with MarkusH, we decided that this should be a bug report.
    216
Back to Top