I'm doing initial migrations on an existing database. Two apps have a
circular dependency, so I break out the migrations like this:
a.0001_initial
a.0002_add_field_that_caused_circular_error
b.0001_initial
Running manage.py migrate will run a.0001 and b.0001 as faked
automatically, but a.0002 will fail because it isn't the first migration
in the app, and because it isn't a CreateModel. So I would have to
manually run "manage.py migrate a 0002 --fake".
The above seems fine if you have one database in one state, and have to do
this once. In any system with multiple environments, with multiple states
of the database, with a lot of automation, where you could normally just
run migrate and it always get your database up to speed, you now have to
write a script that does 0002 --fake if the migrations have not been run
yet for app a, otherwise NOT do it. This is very tedious.
Adding a flag to migrations that it always be faked would solve it, so I
could go back to always just running "migrate". If there are other
solutions that are better for getting around it, I'm all ears :)
--
Ticket URL: <https://code.djangoproject.com/ticket/24375>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* needs_better_patch: => 0
* stage: Unreviewed => Accepted
* needs_tests: => 0
* needs_docs: => 0
Comment:
I think there is a reasonable feature request here, except that it should
not be an "always-fake" attribute. This doesn't really make conceptual
sense, since the need for faking is never inherent in a migration, it
always depends on the state of the database the migration is run against.
In your particular situation, it may be true that you will only ever run
these migrations against existing databases (I guess you don't use
Django's test runner?), but that's an unusual scenario (and I doubt it's
even true in your case -- you'll never again ever spin up a new
environment of this app?)
The version of this that makes sense to me is a migration attribute that
says "I should be considered a part of the initial migration, for purposes
of auto-faking when Django detects that the tables for this app already
exist."
I would suggest that this attribute be named `initial`, and always be set
on the actual initial migration too. Then there is no longer any implicit
special-casing of the first migration; the auto-fake behavior would just
auto-fake until it reaches a migration without `initial = True`.
Making this change would allow us to get rid of the special case mentioned
in the documentation, where sometimes if two initial migrations are
created you have to manually fake the second one.
--
Ticket URL: <https://code.djangoproject.com/ticket/24375#comment:1>
* owner: nobody => akulakov
* status: new => assigned
--
Ticket URL: <https://code.djangoproject.com/ticket/24375#comment:2>
Comment (by haeric):
Yes, great idea, 'initial' is an even better solution to this problem for
all the reasons you mentioned. Neat bonus to get rid of the magic
detection for initial migration!
For my particular problem I ended up making a custom AddField that simply
does nothing if the field is already there. But an `initial` would
certainly solve it, in my mind, more elegantly.
--
Ticket URL: <https://code.djangoproject.com/ticket/24375#comment:3>
Comment (by MarkusH):
There is an issue with squashed migrations we didn't consider when
introducing --fake-initial:
https://code.djangoproject.com/ticket/24628#comment:2 . I think a squashed
migration that replaces the first n migrations inside an app should be
considered to have `initial = True` too. I think we should treat that as
part of this patch, though in a separate commit referencing to #24628 and
#24184
--
Ticket URL: <https://code.djangoproject.com/ticket/24375#comment:4>
* has_patch: 0 => 1
Comment:
[https://github.com/django/django/pull/4420 PR]
--
Ticket URL: <https://code.djangoproject.com/ticket/24375#comment:5>
* needs_better_patch: 0 => 1
--
Ticket URL: <https://code.djangoproject.com/ticket/24375#comment:6>
* needs_better_patch: 1 => 0
--
Ticket URL: <https://code.djangoproject.com/ticket/24375#comment:7>
* stage: Accepted => Ready for checkin
--
Ticket URL: <https://code.djangoproject.com/ticket/24375#comment:8>
* status: assigned => closed
* resolution: => fixed
Comment:
In [changeset:"db97a8849519a3933bf4abd2184efd68ebc21965" db97a884]:
{{{
#!CommitTicketReference repository=""
revision="db97a8849519a3933bf4abd2184efd68ebc21965"
Fixed #24375 -- Added Migration.initial attribute
The new attribute is checked when the `migrate --fake-initial` option
is used. initial will be set to True for all initial migrations (this
is particularly useful when initial migrations are split) as well as
for squashed migrations.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/24375#comment:9>