How to revert the last migration?
Solution 1:
You can revert by migrating to the previous migration.
For example, if your last two migrations are:
0010_previous_migration
0011_migration_to_revert
Then you would do:
./manage.py migrate my_app 0010_previous_migration
You don't actually need to use the full migration name, the number is enough, i.e.
./manage.py migrate my_app 0010
You can then delete migration 0011_migration_to_revert
.
If you're using Django 1.8+, you can show the names of all the migrations with
./manage.py showmigrations my_app
To reverse all migrations for an app, you can run:
./manage.py migrate my_app zero
Solution 2:
The answer by Alasdair covers the basics
- Identify the migrations you want by
./manage.py showmigrations
-
migrate
using the app name and the migration name
But it should be pointed out that not all migrations can be reversed. This happens if Django doesn't have a rule to do the reversal. For most changes that you automatically made migrations by ./manage.py makemigrations
, the reversal will be possible. However, custom scripts will need to have both a forward and reverse written, as described in the example here:
https://docs.djangoproject.com/en/1.9/ref/migration-operations/
How to do a no-op reversal
If you had a RunPython
operation, then maybe you just want to back out the migration without writing a logically rigorous reversal script. The following quick hack to the example from the docs (above link) allows this, leaving the database in the same state that it was after the migration was applied, even after reversing it.
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
def forwards_func(apps, schema_editor):
# We get the model from the versioned app registry;
# if we directly import it, it'll be the wrong version
Country = apps.get_model("myapp", "Country")
db_alias = schema_editor.connection.alias
Country.objects.using(db_alias).bulk_create([
Country(name="USA", code="us"),
Country(name="France", code="fr"),
])
class Migration(migrations.Migration):
dependencies = []
operations = [
migrations.RunPython(forwards_func, lambda apps, schema_editor: None),
]
This works for Django 1.8, 1.9
Update: A better way of writing this would be to replace lambda apps, schema_editor: None
with migrations.RunPython.noop
in the snippet above. These are both functionally the same thing. (credit to the comments)
Solution 3:
Don't delete the migration file until after the reversion. I made this mistake and without the migration file, the database didn't know what things to remove.
python manage.py showmigrations
python manage.py migrate {app name from show migrations} {00##_migration file.py}
If you want to revert all migrations, use zero
as the name of the migration:
python manage.py migrate app_name_here zero
Delete the migration file. Once the desired migration is in your models...
python manage.py makemigrations
python manage.py migrate