Every Django project may encounter a steady increase in a number of migrations over time. One way to lower their quantity is to use squashing. Squashing amounts to taking contents of few migrations and connecting them into one. This would reduce their number, but what happens if we squash a bunch of migrations that were already partially applied to one of application’s instances?

Let’s consider following situation. We have three different migrations in our app:

We squashed them to one:

If we inspect newly created migration’s code we discover that django placed a clear sign that our new migration replaces old ones:

If we ever decided to set up another instance of our application, it django would execute our squashed migration only (0001_initial_squashed_0003_rental).

What if we found ourselves in a less pleasant situation, when we have our instance partially migrated? Let’s say we have executed migrations 0001 and 0002:

Unless we deleted original migration files (django won’t touch them) we will be able to just run ./manage.py migrate. Django will handle this situation.