How to revert the last migration in Django

One of Django’s cool features is its migration system, which enables seamless schema and data modifications. There are times when you might want to undo the last migration, whether it be due to an error or a change in requirements.

When/why revert a migration?

Reverting a migration can be necessary for multiple reasons — especially in a dev environment:

  • Mistakes: It’s possible that the last migration contained errors that need to be fixed.
  • Change in requirements: Sometimes, after applying a migration, project requirements might change, necessitating a rollback.
  • Testing: You might be testing a migration and want to reset the state for further tests.

Use migrate to revert a specific migration

The migrate command in Django is not just for moving forward; it can also be used to rollback migrations. To revert the last migration, you need to use the migration name that preceded it.

Here’s a step-by-step process:

  1. List migrations: First, it’s good practice to list all the migrations for an app to double-check the migration names and their applied status.

    python manage.py showmigrations your_app_name

    This will show a list of migrations for your_app_name with an [X] next to the ones that have been applied, for instance:

    • …
    • 0009_orders
    • 0010_itemization
  2. Revert a specific migration: If you want to revert the last migration, take note of the migration immediately before it. Then, use the migrate command followed by the app name and the preceding migration name, for instance:

    python manage.py migrate your_app_name 0009_orders

    By doing this, Django will rollback all migrations up to, but not including, 0010_itemization.

N.B. Passing an earlier migration will rollback all the following migrations up to, but not including, that one.

Revert all migrations for a given app

There might be scenarios where you need to undo all the migrations for a specific app, possibly due to a significant structural change or when resetting an app state entirely. Django makes this process straightforward, just use the migrate command followed by the app name and zero. The zero keyword instructs Django to rollback all migrations for the specified app:

python manage.py migrate your_app_name zero

Executing the above command will revert all migrations for your_app_name and bring the database schema for that app back to its initial state.

A word of caution

Before reverting a migration, especially in a production environment:

  • Backup: Always backup your database. Reverting migrations, especially ones that delete data or columns, can lead to data loss.
  • Dependencies: Be cautious of dependencies between migrations across different apps. Rolling back a migration in one app might affect another app state.

N.B. Personally, I only revert migrations in local/dev/staging environments. Once the migration is run in production, I’d rather create a new migration to undo any undesired changes.

Onward!