1311👍
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
59👍
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
- [Django]-Django: How can I create a multiple select form?
- [Django]-Factory-boy create a list of SubFactory for a Factory
- [Django]-Filtering using viewsets in django rest framework
49👍
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)
- [Django]-Separating form input and model validation in Django?
- [Django]-Django Cache cache.set Not storing data
- [Django]-Http POST drops port in URL
16👍
Here is my solution, since the above solution do not really cover the use-case, when you use RunPython
.
You can access the table via the ORM with
from django.db.migrations.recorder import MigrationRecorder
>>> MigrationRecorder.Migration.objects.all()
>>> MigrationRecorder.Migration.objects.latest('id')
Out[5]: <Migration: Migration 0050_auto_20170603_1814 for model>
>>> MigrationRecorder.Migration.objects.latest('id').delete()
Out[4]: (1, {u'migrations.Migration': 1})
So you can query the tables and delete those entries that are relevant for you. This way you can modify in detail. With RynPython
migrations you also need to take care of the data that was added/changed/removed. The above example only displays, how you access the table via Djang ORM.
- [Django]-Redirect to Next after login in Django
- [Django]-Django get objects not referenced by foreign key
- [Django]-Django models: mutual references between two classes and impossibility to use forward declaration in python
13👍
To revert a migration:
python manage.py migrate <APP_NAME> <MIGRATION_NUMBER_PREFIX>
MIGRATION_NUMBER_PREFIX
is the number prefix of the migration you want to revert to, for instance 0001
to go to 0001_initial.py
migration. then you can delete that migration.
You can use
zero
as your migration number to revert all migrations of an app.
- [Django]-Django custom field validator vs. clean
- [Django]-How to get username from Django Rest Framework JWT token
- [Django]-Django south migration – Adding FULLTEXT indexes
12👍
I did this in 1.9.1 (to delete the last or latest migration created):
-
rm <appname>/migrations/<migration #>*
example:
rm myapp/migrations/0011*
-
logged into database and ran this SQL (postgres in this example)
delete from django_migrations where name like '0011%';
I was then able to create new migrations that started with the migration number that I had just deleted (in this case, 11).
- [Django]-Embedding JSON objects in script tags
- [Django]-Troubleshooting Site Slowness on a Nginx + Gunicorn + Django Stack
- [Django]-Logging in Django and gunicorn
10👍
The other thing that you can do is delete the table created manually.
Along with that, you will have to delete that particular migration file. Also, you will have to delete that particular entry in the django-migrations table(probably the last one in your case) which correlates to that particular migration.
- [Django]-How can I handle Exceptions raised by dango-social-auth?
- [Django]-Django: why i can't get the tracebacks (in case of error) when i run LiveServerTestCase tests?
- [Django]-UUID as default value in Django model
10👍
First: find the previous migrations of your app,
python manage.py showmigrations
eg:
bz
[X] 0001_initial
[ ] 0002_bazifff
If you want rollback 0002_bazifff migrations,
python manage.py migrate bz 0001_initial
If you want rollback 0001_initial Or all
python manage.py migrate bz zero
It seems can’t rollback 0001 only
- [Django]-Querying django migrations table
- [Django]-Using Cloudfront with Django S3Boto
- [Django]-Django: sqlite for dev, mysql for prod?
8👍
You can revert by migrating to the previous migration.
For example use below command:
./manage.py migrate example_app one_left_to_the_last_migration
then delete last_migration
file.
- [Django]-Django can' t load Module 'debug_toolbar': No module named 'debug_toolbar'
- [Django]-Django: Filter a Queryset made of unions not working
- [Django]-Why is factory_boy superior to using the ORM directly in tests?
7👍
If you are facing trouble while reverting back the migration, and somehow have messed it, you can perform fake
migrations.
./manage.py migrate <name> --ignore-ghost-migrations --merge --fake
For django version < 1.7 this will create entry in south_migrationhistory
table, you need to delete that entry.
Now you’ll be able to revert back the migration easily.
PS: I was stuck for a lot of time and performing fake migration and then reverting back helped me out.
- [Django]-Django substr / substring in templates
- [Django]-Sending HTML email in django
- [Django]-Django admin and MongoDB, possible at all?
3👍
This answer is for similar cases if the top answer by Alasdair does not help. (E.g. if the unwanted migration is created soon again with every new migration or if it is in a bigger migration that can not be reverted or the table has been removed manually.)
…delete the migration, without creating a new migration?
TL;DR: You can delete a few last reverted (confused) migrations and make a new one after fixing models. You can also use other methods to configure it to not create a table by migrate command. The last migration must be created so that it match the current models.
Cases why anyone do not want to create a table for a Model that must exist:
A) No such table should exist in no database on no machine and no conditions
- When: It is a base model created only for model inheritance of other model.
- Solution: Set
class Meta: abstract = True
B) The table is created rarely, by something else or manually in a special way.
- Solution: Use
class Meta: managed = False
The migration is created, but never used, only in tests. Migration file is important, otherwise database tests can’t run, starting from reproducible initial state.
C) The table is used only on some machine (e.g. in development).
- Solution: Move the model to a new application that is added to INSTALLED_APPS only under special conditions or use a conditional
class Meta: managed = some_switch
.
D) The project uses multiple databases in settings.DATABASES
- Solution: Write a Database router with method
allow_migrate
in order to differentiate the databases where the table should be created and where not.
The migration is created in all cases A), B), C), D) with Django 1.9+ (and only in cases B, C, D with Django 1.8), but applied to the database only in appropriate cases or maybe never if required so. Migrations have been necessary for running tests since Django 1.8. The complete relevant current state is recorded by migrations even for models with managed=False in Django 1.9+ to be possible to create a ForeignKey between managed/unmanaged models or to can make the model managed=True later. (This question has been written at the time of Django 1.8. Everything here should be valid for versions between 1.8 to the current 2.2.)
If the last migration is (are) not easily revertible then it is possible to cautiously (after database backup) do a fake revert ./manage.py migrate --fake my_app 0010_previous_migration
, delete the table manually.
If necessary, create a fixed migration from the fixed model and apply it without changing the database structure ./manage.py migrate --fake my_app 0011_fixed_migration
.
- [Django]-Using the reserved word "class" as field name in Django and Django REST Framework
- [Django]-Referencing multiple submit buttons in django
- [Django]-Get count of related model efficiently in Django
1👍
there is a good library to use its called djagno-nomad, although not directly related to the question asked, thought of sharing this,
scenario: most of the time when switching to project, we feel like it should revert our changes that we did on this current branch, that’s what exactly this library does, checkout below
- [Django]-Django substr / substring in templates
- [Django]-What are the limitations of Django's ORM?
- [Django]-Django gunicorn sock file not created by wsgi
1👍
All the other answers work great for rolling back linear migrations. However, when the migration is non-linear i.e has multiple leaf nodes and we wish to rollback only one path, then we can do in following way:
X
/ \
A B [A and B can represent any number of linear migrations.]
\ /
Y (merge migration)
If we need to rollback A,B and Y. Then we can do the way other answer states.
i.e python manage.py migrate app X
.
However, if need to only unapply one path i.e, rollback B and Y, perform following steps:
- Unapply only Y. By doing
python manage.py migrate app B (or A; both works)
. - Remove the migration files A and Y for time being from the project location.
- Now unapply B, by doing
python manage.py migrate app X
.
Bring the migration files A and Y to the original location. Now, you can safely delete the unapplied migrations B and Y, if you wish to.
The gist is django can only rollback migrations if the files are present in the location. If you do not want to rollback a migration path (i.e A here), remove it from the project location while performing rollback.
More on this. https://stackoverflow.com/a/71231925/8663277
- [Django]-Django: sqlite for dev, mysql for prod?
- [Django]-How about having a SingletonModel in Django?
- [Django]-How to change User representation in Django Admin when used as Foreign Key?
1👍
Yes there is a Reverse migration command in Django,
To remove th migrations changes from database directly,
for example if you have 4 migrations files in django app named (student)
enter image description here
python manage.py showmigrations
- Total 04 migrations Applied on Student Application.
file structure : migrations file
- file structure showing the migrations file list.
- want to remove last 2 migrations from database,
fire the command ( python manage.py migrate student 0002 )
[Show final migration list in database][5]
- final showmigrations list in database,
- successfully removed the last two migrations changes from databse.
- [Django]-Altering one query parameter in a url (Django)
- [Django]-Django – How to use decorator in class-based view methods?
- [Django]-Import data from excel spreadsheet to django model