How to reset Django migrations
š Mastering Django Migrations: Your Roadmap to Smoother Developmentš
Are you on a coding journey with Django? If so, youāve probably stumbled upon the fascinating world of Django migrations. These little files hold the secrets to changing your database structure, making them crucial for your web appās growth. In this post, weāll take a deep dive into Django migrations, demystify them, and arm you with practical tips to overcome any migration challenges.
The Magic of Django Migrations: An Adventure Worth Taking
Djangoās migration system is like a trusty sidekick, optimized to handle countless migrations. Itās designed to handle complex changes in your database smoothly. So, donāt be alarmed if you accumulate a bunch of migration files in your project ā itās all part of the journey!
However, as your project grows, you might notice some roadblocks, like slower testing. Ever wished for a āpauseā button for migrations? Unfortunately, Django doesnāt have one (yet).
Donāt Worry, Solutions Await!
But hereās the good news: if youāre looking for a cleaner and faster migration process, this guide is your compass. Weāll explore various ways to simplify your migration management. Whether youāre a seasoned Django developer or just starting out, these tips will be your secret weapons.
In the following sections, weāll learn how to:
- Optimize Your Migration Workflow: Find out how to organize your migrations for better performance and easier upkeep.
- Supercharge Your Testing: Discover tricks to speed up testing without compromising accuracy.
- Tidy Up Your History: Learn best practices for keeping your migration history neat and tidy.
By the end of this adventure, youāll be well-prepared to tackle Django migrations confidently. Letās get started and unlock the full potential of your Django projects together!
Ready to begin your Django migration journey? Letās roll! š
Scenario 1:
The django project is still in the development environment and you want to perform a full clean up. You donāt mind throwing the whole database away.
1. Remove the all migrations files within your project
Go through each of your projects apps migration folder and remove everything inside, except the __init__.py
file.
Or if you are using a unix-like OS you can run the following script (inside your project dir):
find . -path "*/migrations/*.py" -not -name "__init__.py" -delete
find . -path "*/migrations/*.pyc" -delete
2. Drop the current database, or delete the db.sqlite3
if it is your case.
3. Create the initial migrations and generate the database schema:
python manage.py makemigrations
python manage.py migrate
And you are good to go š
Scenario 2:
You want to clear all the migration history but you want to keep the existing database.
1. Make sure your models fits the current database schema. The easiest way to do it is trying to create new migrations:
python manage.py makemigrations
OR
VERY USEFUL: If you want to check the migration changes before actually creating a migration file for a particular Django app then you can run the following command.
For eg. the app name is lead_generation
python manage.py makemigrations --dry-run lead_generation
Result:
Migrations for 'lead_generation':
lead_generation/migrations/0001_auto_20230913_1751.py
- Create model AuthenticationModel
- Change Meta options on AuthenticationModel
- Remove field is_successfull from NotificationModel
If there are any pending migration, apply them first.
If you see the message
No changes detected
You are good to go.
2. Clear the migration history for each app
Now you will need to clear the migration history app by app.
First run the showmigrations
command so we can keep track of what is going on:
python manage.py showmigrations
Result:
admin
[X] 0001_initial
[X] 0002_logentry_remove_auto_add
auth
[X] 0001_initial
[X] 0002_alter_permission_value_name_max_length
[X] 0003_alter_user_email_max_length
[X] 0004_alter_user_username_opts
[X] 0005_alter_user_last_login_null
[X] 0006_require_contenttypes_0002
[X] 0007_alter_validators_add_error_messages
contenttypes
[X] 0001_initial
[X] 0002_remove_content_type_name
core
[X] 0001_initial
[X] 0002_remove_mymodel_i
[X] 0003_mymodel_bio
sessions
[X] 0001_initial
Clear the migration history (please note that admin, auth, contenttypes, core and sessions are the name of my app):
python manage.py migrate --fake core zero
The result will be something like this:
Operations to perform: Unapply all migrations: core Running migrations: Rendering model states... DONE Unapplying core.0003_mymodel_bio... FAKED Unapplying core.0002_remove_mymodel_i... FAKED Unapplying core.0001_initial... FAKED
Now run the command showmigrations
again:
python manage.py showmigrations
Result:
admin
[X] 0001_initial
[X] 0002_logentry_remove_auto_add
auth
[X] 0001_initial
[X] 0002_alter_permission_name_max_length
[X] 0003_alter_user_email_max_length
[X] 0004_alter_user_username_opts
[X] 0005_alter_user_last_login_null
[X] 0006_require_contenttypes_0002
[X] 0007_alter_validators_add_error_messages
contenttypes
[X] 0001_initial
[X] 0002_remove_content_type_name
core
[X] 0001_initial
[X] 0002_remove_mymodel_i
[X] 0003_mymodel_bio
sessions
[X] 0001_initial
NOTE : You must do that for all the apps you want to reset the migration history.
Here also if you find difficulty in resetting migrations from Django project, You can achieve it by using an alternate yet effective method.
If you are using Mysql Database you can run a Command and then execute the Mysql query.
Run the following command:
python manage.py dbshell
Then execute a mysql query inside the shell
TRUNCATE TABLE django_migrations;
The above command will delete all the migration history from the Django projectās Migration table, which keeps a log and tracks the history of migrations performed app-wise.
3. Remove the actual migration files.
Go through each of your projects apps migration folder and remove everything inside, except for the __init__.py
file.
Or if you are using a unix-like OS you can run the following script (inside your project directory):
find . -path "*/migrations/*.py" -not -name "__init__.py" -delete
find . -path "*/migrations/*.pyc" -delete
PS: The example above will remove all the migrations file inside your project.
Run the showmigrations
command again:
python manage.py showmigrations
Result:
admin
[X] 0001_initial
[X] 0002_logentry_remove_auto_add
auth
[X] 0001_initial
[X] 0002_alter_permission_name_max_length
[X] 0003_alter_user_email_max_length
[X] 0004_alter_user_username_opts
[X] 0005_alter_user_last_login_null
[X] 0006_require_contenttypes_0002
[X] 0007_alter_validators_add_error_messages
contenttypes
[X] 0001_initial
[X] 0002_remove_content_type_name
core
(no migrations)
sessions
[X] 0001_initial
4. Create the initial migrations
python manage.py makemigrations
Result:
Migrations for 'core': 0001_initial.py: - Create model MyModel
5. Fake the initial migration
In this case you wonāt be able to apply the initial migration because the database table already exists. What we want to do is to fake this migration instead:
python manage.py migrate --fake-initial
Result:
Operations to perform: Apply all migrations: admin, core, contenttypes, auth, sessions Running migrations: Rendering model states... DONE Applying core.0001_initial... FAKED
Run showmigrations
again:
python manage.py showmigrations
Result:
admin
[X] 0001_initial
[X] 0002_logentry_remove_auto_add
auth
[X] 0001_initial
[X] 0002_alter_permission_name_max_length
[X] 0003_alter_user_email_max_length
[X] 0004_alter_user_username_opts
[X] 0005_alter_user_last_login_null
[X] 0006_require_contenttypes_0002
[X] 0007_alter_validators_add_error_messages
contenttypes
[X] 0001_initial
[X] 0002_remove_content_type_name
core
[X] 0001_initial
sessions
[X] 0001_initial
And we are all set up š