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 Carl Meyer, 10 years ago

Summary: Add ability to mark migration as fake in MigrationAdd ability to mark migration as "part of initial" in Migration
Triage Stage: UnreviewedAccepted

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.

comment:2 by andrei kulakov, 10 years ago

Owner: changed from nobody to andrei kulakov
Status: newassigned

comment:3 by Håkon Erichsen, 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.

Last edited 10 years ago by Håkon Erichsen (previous) (diff)

comment:4 by Markus Holtermann, 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:5 by Tim Graham, 10 years ago

Has patch: set

comment:6 by Tim Graham, 9 years ago

Patch needs improvement: set

comment:7 by Tim Graham, 9 years ago

Patch needs improvement: unset

comment:8 by Tim Graham, 9 years ago

Triage Stage: AcceptedReady for checkin

comment:9 by Tim Graham <timograham@…>, 9 years ago

Resolution: fixed
Status: assignedclosed

In db97a884:

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.

Note: See TracTickets for help on using tickets.
Back to Top