Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to revert the last migration?

I've made a migration that added a new table and want to revert it and delete the migration, without creating a new migration.

How do I do it? Is there a command to revert last migration and then I can simply delete the migration file?

like image 730
Ronen Ness Avatar asked Aug 20 '15 16:08

Ronen Ness


People also ask

How do I roll back the last migration?

rails db:rollback:primary , where primary is the name of the database in your config/databases. yml file, to rollback the last migration. You can make usage of the STEPS attribute here, as usual. rails db:rollback:primary VERSION=your_migration_timestamp , to rollback only the provided migration version.

How do I undo migration?

Undoing Migrations​ With migration you can revert to old state by just running a command. You can use db:migrate:undo , this command will revert most the recent migration. You can revert back to the initial state by undoing all migrations with the db:migrate:undo:all command.


2 Answers

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 
like image 108
Alasdair Avatar answered Sep 19 '22 13:09

Alasdair


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)

like image 24
AlanSE Avatar answered Sep 19 '22 13:09

AlanSE