Opened 10 years ago
Closed 9 years ago
#24375 closed New feature (fixed)
Add ability to mark migration as "part of initial" in Migration
Reported by: | Håkon Erichsen | Owned by: | andrei kulakov |
---|---|---|---|
Component: | Migrations | Version: | 1.7 |
Severity: | Normal | Keywords: | fake migrations |
Cc: | Triage Stage: | Ready for checkin | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
I would like to add a property on a Migration to always fake it. Here's the use-case:
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 :)
Change History (9)
comment:1 by , 10 years ago
Summary: | Add ability to mark migration as fake in Migration → Add ability to mark migration as "part of initial" in Migration |
---|---|
Triage Stage: | Unreviewed → Accepted |
comment:2 by , 10 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:3 by , 10 years ago
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.
comment:4 by , 10 years ago
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
comment:6 by , 10 years ago
Patch needs improvement: | set |
---|
comment:7 by , 9 years ago
Patch needs improvement: | unset |
---|
comment:8 by , 9 years ago
Triage Stage: | Accepted → Ready for checkin |
---|
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 withoutinitial = 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.