How to reset Django migrations

Mustahib Majgaonkar
5 min readSep 13, 2023

--

šŸš€ 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:

  1. Optimize Your Migration Workflow: Find out how to organize your migrations for better performance and easier upkeep.
  2. Supercharge Your Testing: Discover tricks to speed up testing without compromising accuracy.
  3. 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 šŸ˜„

--

--

Responses (1)