Prevent forgotten migrations in Django projects with pre-commit hook

Our Blog

Lukáš Letovanec20.05.202110 minutes

Check migrations created.................................................Failed - hook id: check-migrations-created - exit code: 1 Migrations were not created!

In this post, we will talk about a simple but useful pre-commit hook for Django projects. The purpose of the mentioned hook is to prevent committing changes to the git repository after modifying some Django model without creating an appropriate migration.

Migrations checker

If you are not familiar with pre-commit I suggest you to read the pre-commit introduction first to get a better idea of how pre-commit hooks work. Forgotten migration is not that big of a deal, but it can cause annoying bugs for your colleagues as well as inconsistency in git history so it's better to prevent such problems right away. The hook accomplishes this by running makemigrations command with --dry-run option and checking its output.

Hook setup

The setup is straightforward - first copy the following lines to your .pre-commit-config.yaml file.

repos: # only add this if you don't have some repos in config already - repo: https://github.com/remastr/pre-commit-django-check-migrations rev: v0.1.0 hooks: - id: check-migrations-created args: [ --exec-command=poetry run python, --manage-path=sample_project/manage.py, ]

The hook takes two optional arguments which you will almost definitely want to set yourself depending on your project.

Argument --manage-path should, as the name implies, specify the path to the manage.py file of the project. This path should be relative to the root of your git repository. The default value is ./src/manage.py.

Argument --exec-command specifies the command that will be used to execute manage.py. Default is python3. If you are using docker-compose for your project this can be set to docker-compose exec sample_project python for example. Similar to this, if you are using poetry or pipenv for managing your dependencies you can reuse them in this hook with poetry run python / pipenv run python. If you opt to not use any of these, you can still use the hook but you will need to add Django as an additional dependency. Your config would then look similar to this:

repos: - repo: https://github.com/remastr/pre-commit-django-check-migrations rev: v0.1.0 hooks: - id: check-migrations-created args: [--manage-path=sample_project/manage.py] additional_dependencies: [django==3.2.1]

Django will be then automatically installed to the hooks virtual environment on the first commit you make.

The migrations check runs only if some of models.py files in your project have been changed. Output of the pre-commit check that has not passed successfully will look something like this:

$ git commit -m "testing hook" . . . Check migrations created.................................................Failed - hook id: check-migrations-created - exit code: 1 Migrations were not created!

Then just run the makemigrations command and you are good to go!

© 2023 Created by Remaster. All rights reserved.

Company ID: CZ10666648