damd
damd

Reputation: 6957

Optimize a squashed migration in Django

I have created a squashed Django migration that looks similar to this:

add field "name"
run sql "CREATE FUNCTION x"
add field "age"
remove field "name"
run sql "DROP FUNCTION x"

Since Django cannot fully optimize the code between two run sql blocks, it is expected that add field "name" and remove field "name" are not optimized away. However, I know that the two SQL runs affects nothing relevant, so I can manually delete the run sql parts.

After having manually removed the run sql parts, is there any way to have Django run only the optimization step on the results?

Upvotes: 0

Views: 532

Answers (1)

Joel Hillacre
Joel Hillacre

Reputation: 36

I wrote a command that uses Django's MigrationOptimizer to rewrite a single migration file, specifically for this scenario. I posted it as a gist here:

https://gist.github.com/jhillacre/7fa8c182dd821387d4cf1fdb9371dcd7

I've tested this in Django 1.11 using python 3.6. Not sure if there are changes required for Django 2+.

Gotchas include:

  • the optimizer removing the initial flag from the migration.
  • swappable dependencies being being distorted

I always diff the optimized migration and the original migration to make sure the changes regarding initial and dependencies are reverted.

Alternatively, you could remove these operation before squashing using the RunPython or RunSql elidable argument. From the docs:

The optional elidable argument determines whether or not the operation will be removed (elided) when squashing migrations. link

Upvotes: 2

Related Questions