[Django] #25945: Unabled to refer to partially-run squashed migrations in newer migrations.

25 views
Skip to first unread message

Django

unread,
Dec 15, 2015, 9:38:35 PM12/15/15
to django-...@googlegroups.com
#25945: Unabled to refer to partially-run squashed migrations in newer migrations.
-------------------------+-------------------------------------------------
Reporter: jarekwg | Owner: nobody
Type: Bug | Status: new
Component: | Version: 1.9
Migrations | Keywords: squashmigrations partially run
Severity: Normal | dependencies
Triage Stage: | Has patch: 0
Unreviewed |
Easy pickings: 0 | UI/UX: 0
-------------------------+-------------------------------------------------
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.

--
Ticket URL: <https://code.djangoproject.com/ticket/25945>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Dec 15, 2015, 9:42:16 PM12/15/15
to django-...@googlegroups.com
#25945: Unable to refer to partially-run squashed migrations in newer migrations.
-------------------------------------+-------------------------------------

Reporter: jarekwg | Owner: nobody
Type: Bug | Status: new
Component: Migrations | Version: 1.9
Severity: Normal | Resolution:
Keywords: squashmigrations | Triage Stage:
partially run dependencies | Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by jarekwg):

* needs_better_patch: => 0
* needs_tests: => 0
* needs_docs: => 0


--
Ticket URL: <https://code.djangoproject.com/ticket/25945#comment:1>

Django

unread,
Dec 21, 2015, 7:16:49 AM12/21/15
to django-...@googlegroups.com
#25945: Unable to refer to partially-run squashed migrations in newer migrations.
-------------------------------------+-------------------------------------

Reporter: jarekwg | Owner: nobody
Type: Bug | Status: new
Component: Migrations | Version: 1.9
Severity: Normal | Resolution:
Keywords: squashmigrations | Triage Stage: Accepted
partially run dependencies |

Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by timgraham):

* stage: Unreviewed => Accepted


--
Ticket URL: <https://code.djangoproject.com/ticket/25945#comment:2>

Django

unread,
Jan 3, 2016, 8:05:08 AM1/3/16
to django-...@googlegroups.com
#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:

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

unread,
Jan 6, 2016, 6:35:12 AM1/6/16
to django-...@googlegroups.com
#25945: Referring to partially run squashed migrations
-------------------------------------+-------------------------------------
Reporter: jarekwg | Owner: jarekwg
Type: Bug | Status: assigned

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):

* status: new => assigned
* owner: nobody => jarekwg


Old 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

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`, using fancy logic to
ensure valid references to inapplicable migrations are appropriately
rerouted.

--

--
Ticket URL: <https://code.djangoproject.com/ticket/25945#comment:4>

Django

unread,
Jan 6, 2016, 10:10:35 AM1/6/16
to django-...@googlegroups.com
#25945: Referring to partially run squashed migrations
-------------------------------------+-------------------------------------
Reporter: jarekwg | Owner: jarekwg
Type: Bug | Status: assigned
Component: Migrations | Version: 1.9
Severity: Normal | Resolution:
Keywords: make squash | Triage Stage: Accepted
migrations partially run |
dependencies |
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by jarekwg):

* has_patch: 0 => 1


Old 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`, using fancy logic
> to ensure valid references to inapplicable migrations are appropriately
> rerouted.

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`, using fancy logic to
ensure valid references to inapplicable migrations are appropriately
rerouted.

[https://github.com/django/django/compare/master...jarekwg:ticket_25945 /
Patch]
[https://github.com/django/django/pull/5939 / Pull Request]

--

--
Ticket URL: <https://code.djangoproject.com/ticket/25945#comment:5>

Django

unread,
Feb 24, 2016, 11:30:36 AM2/24/16
to django-...@googlegroups.com
#25945: Referring to partially run squashed migrations
-------------------------------------+-------------------------------------
Reporter: jarekwg | Owner: jarekwg
Type: Bug | Status: assigned
Component: Migrations | Version: 1.9
Severity: Normal | Resolution:
Keywords: make squash | Triage Stage: Accepted
migrations partially run |
dependencies |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by timgraham):

* needs_better_patch: 0 => 1


Comment:

Left comments for improvement on the pull request.

--
Ticket URL: <https://code.djangoproject.com/ticket/25945#comment:6>

Django

unread,
May 8, 2016, 7:39:58 AM5/8/16
to django-...@googlegroups.com
#25945: Referring to partially run squashed migrations
-------------------------------------+-------------------------------------
Reporter: jarekwg | Owner: jarekwg
Type: Bug | Status: assigned
Component: Migrations | Version: master
Severity: Normal | Resolution:
Keywords: make squash | Triage Stage: Ready for
migrations partially run | checkin

dependencies |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by MarkusH):

* needs_better_patch: 1 => 0
* version: 1.9 => master
* stage: Accepted => Ready for checkin


--
Ticket URL: <https://code.djangoproject.com/ticket/25945#comment:7>

Django

unread,
May 8, 2016, 7:54:54 AM5/8/16
to django-...@googlegroups.com
#25945: Referring to partially run squashed migrations
-------------------------------------+-------------------------------------
Reporter: jarekwg | Owner: jarekwg
Type: Bug | Status: closed
Component: Migrations | Version: master
Severity: Normal | Resolution: fixed

Keywords: make squash | Triage Stage: Ready for
migrations partially run | checkin
dependencies |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Markus Holtermann <info@…>):

* status: assigned => closed
* resolution: => fixed


Comment:

In [changeset:"509379a161d179f9e973fbaf6393e879531756f6" 509379a1]:
{{{
#!CommitTicketReference repository=""
revision="509379a161d179f9e973fbaf6393e879531756f6"
Fixed #25945, #26292 -- Refactored MigrationLoader.build_graph()
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/25945#comment:8>

Reply all
Reply to author
Forward
0 new messages