#25945: Makemigrations referring to squashed migrations
-------------------------------------+-------------------------------------
     Reporter:  jarekwg              |                    Owner:  nobody
         Type:  Bug                  |                   Status:  new
    Component:  Migrations           |                  Version:  1.9
     Severity:  Normal               |               Resolution:
     Keywords:  make squash          |             Triage Stage:  Accepted
  migrations partially run           |
  dependencies                       |
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
Changes (by jarekwg):

 * keywords:  squashmigrations partially run dependencies => make squash
     migrations partially run dependencies


Old description:

> From Django docs:
> "These files are marked to say they replace the previously-squashed
> migrations, so they can coexist with the old migration files, and Django
> will intelligently switch between them depending where you are in the
> history. If you’re still part-way through the set of migrations that you
> squashed, it will keep using them until it hits the end and then switch
> to the squashed history, while new installs will just use the new
> squashed migration and skip all the old ones."
>
> However there seems to be a caviot in that you can't refer to partially
> squashed migrations.
> Example:
>
> {{{
> my_app/migrations/
> 0001_initial.py
> 0002_blah.py -> dep on 0001_initial
> 0001_initial_squashed_0002_blah.py -> replaces 0001_initial and 0002_blah
> 0003_ohnoes.py -> dep on ????
> }}}
>

> If we try to make 0003 depend on 0001_initial_squashed_0002_blah, then we
> get a NodeNotFoundError if the database is only up to 0001_initial: it
> has 'intelligently switched' to the unsquashed reality in which
> 0001_initial_squashed_0002_blah does not exist.
>
> Conversely if we try to make 0003 depend on 0002_blah, then we get a
> NodeNotFoundError when trying to create a new database: it has
> 'intelligently switched' to the squashed reality in which 0002_blah does
> not exist.
>
> Proposed solution: Use
>
> {{{
> dependencies = [('my_app', '0001_initial_squashed_0002_blah'),]
> }}}
>
> and for cases where the migration tree does not contain
> 0001_initial_squashed_0002_blah, have it inspect the 'replaces' list in
> 0001_initial_squashed_0002_blah.py, pick out the most recent migration
> (ie 0002_blah.py) and use that instead.
> I'm happy to implement this myself if given the thumbs up for the
> proposed approach.

New description:

 Consider the migration tree defined by:
 {{{
 my_app/migrations/
 0001_initial.py
 0002_blah.py -> dep on 0001_initial
 0001_initial_squashed_0002_blah.py -> replaces 0001_initial and 0002_blah
 0003_ohnoes.py -> dep on ????
 }}}

 If we try to make `0003` depend on `0001_initial_squashed_0002_blah`, then
 we get a NodeNotFoundError if the database is only up to `0001_initial`:
 it is currently in the 'unsquashed reality' in which
 `0001_initial_squashed_0002_blah` does not exist. Creating new databases
 from this setup does not raise any problems, nor does running the
 migrations on databases that aren't part-way through a squashed migration
 series since these will live in the 'squashed reality'.

 If we try to make `0003` depend on `0002_blah`, then things work fine in
 all cases.

 However `makemigrations` chooses to point newly created migrations at the
 squashed migration `0001_initial_squashed_0002_blah` rather than the last
 of the unsquashed ones `0002_blah`, causing the problem described above
 and making it unobvious that new migrations should still point at the old
 replaced migrations up until the point at which the squashed migrations
 get transitioned to normal migrations.

 Proposed solution:

 Fully support listing the dependency both ways, as
 `0001_initial_squashed_0002_blah` and as `0002_blah`. For cases where the
 migration tree is in the unsquashed reality and thus does not contain
 `0001_initial_squashed_0002_blah`, have it inspect the 'replaces' list in
 `0001_initial_squashed_0002_blah.py`, pick out the most recent migration
 (ie `0002_blah`) and use that instead.

 Another (perhaps cleaner, yet less clear) solution:

 Have `makemigrations` not point newly created migrations at squashed
 migrations, but rather at the squashed migrations' last dependency. This
 would solve the issue with `makemigrations` automatically creating
 problematic migrations. It would be cleaner as there'd only be one
 ''correct'' migration to point to, however it could result in confusion
 for people manually creating their migrations and pointing them at the
 wrong thing.

--

--
Ticket URL: <https://code.djangoproject.com/ticket/25945#comment:3>
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/065.51fba2b66d0fcdd4062afc57d4e22ca2%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to