Resolve migration errors
Project description
django-migration-fixer
Resolve django makemigrations multiple leaf nodes in the migration graph
by ensuring that migration files and dependencies are always ordered regardless of remote changes.
Features
- 100% test coverage.
- Maintain a consistent migration history when conflicts occur as a result of changes made using different versions of the default branch.
- Resolve migration conflicts on PR branches
- Resolve migration conflicts on the default branch (NOT RECOMMENDED)
- Supports default migration modules i.e (
0001_....py
) - Re-number all migrations using the last migration on the default branch i.e
main|master|develop
depending on your setup.
Installation
$ pip install django-migration-fixer
Add migration_fixer
to your INSTALLED_APPS
INSTALLED_APPS = [
...,
"migration_fixer",
...,
]
Usage
$ python manage.py makemigrations --fix
By default this uses main
as the default branch
Specifying a different default branch
Run:
$ python manage.py makemigrations -b master --fix
Github Actions
NOTE: :warning:
To get this action to work you'll need to install django-migration-fixer and update your
INSTALLED_APPS
setting.See: https://github.com/tj-django/django-clone for an example setup.
name: Fix django migrations
on:
pull_request:
branches:
- main
jobs:
fix-migrations:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.6.x'
- name: Upgrade pip
run: |
pip install -U pip
- name: Install project dependencies
run: |
make install
- name: Run django-migration-fixer
uses: tj-django/django-migration-fixer@v1.1.1
with:
managepy-path: /path/to/manage.py
- name: Verify Changed files
uses: tj-actions/verify-changed-files@v7.1
id: verify-changed-files
with:
files: |
/path/to/migrations
- name: Commit migration changes
if: steps.verify-changed-files.outputs.files_changed == 'true'
run: |
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
git add /path/to/migrations
git commit -m "Update migrations"
- name: Push migration changes
if: steps.verify-changed-files.outputs.files_changed == 'true'
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
branch: ${{ github.ref }}
Test Platforms
Example
Local branch changes
After merging the default branch
After running django-migration-fixer
More Examples
Branch: main
├── app
│ ├── migrations
│ ├── 0001_initial.py
│ ├── 0002_auto_20210521_2328.py
Branch: feature/test-a
├── app
│ ├── migrations
│ ├── 0001_initial.py
│ ├── 0002_auto_20210521_2328.py
│ ├── 0003_auto_20210522_1128.py
Branch:feature/test-b
├── app
│ ├── migrations
│ ├── 0001_initial.py
│ ├── 0002_auto_20210521_2328.py
│ ├── 0003_auto_20210522_1228.py
Both feature/test-a
and feature/test-b
share the last migration on main
(0002_auto_20210521_2328.py
)
Once feature/test-a
is merged into main
you run into the problem of resolving migrations on feature/test-b
which was dependent on 0002_auto_20210521_2328.py
Branch: main
├── app
│ ├── migrations
│ ├── 0001_initial.py
│ ├── 0002_auto_20210521_2328.py
│ ├── 0003_auto_20210522_1128.py
Branch: feature/test-b
├── app
│ ├── migrations
│ ├── 0001_initial.py
│ ├── 0002_auto_20210521_2328.py
│ ├── 0003_auto_20210522_1128.py \___________________ Both dependent on 0002_auto_20210521_2328.py
│ ├── 0003_auto_20210522_1228.py /
Running makemigrations
fails with the following error:
CommandError: Conflicting migrations detected; multiple leaf nodes in the migration graph: (0003_auto_20210522_1128, 0003_auto_20210522_1228 in app).
To fix them run 'python manage.py makemigrations --merge'
Using the --merge
option creates a new migration file which might not be desired.
Solution
django-migration-fixer
identifies changes between the default branch main
, and the feature branch feature/test-b
and maintains a consistent dependency history as shown below:
Branch: feature/test-b
├── app
│ ├── migrations
│ ├── 0001_initial.py
│ ├── 0002_auto_20210521_2328.py
│ ├── 0003_auto_20210522_1128.py
│ ├── 0004_auto_20210522_1228.py # Renames: '0003_auto_20210522_1228.py' → '0004_auto_20210522_1228.py'
0004_auto_20210522_1228.py
...
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('app', '0003_auto_20210522_1128'), # Replaced '0002_auto_20210521_2328' → '0003_auto_20210522_1128'
]
operations = [
...
]
NOTE: :warning:
This also works when there are conflicts detected on the default branch.
i.e You can run
python manage.py makemigrations --fix
on themain
branch which relies on primitively picking the first migration file.e.g
(0003_auto_20210522_1128, 0003_auto_20210522_1228 in app)
would result in0003_auto_20210522_1128.py
being picked as the base migration which might not be accurate in every case and is not recommended.
Assumptions
The final migration on the default branch would be used as the base for all subsequent migrations.
Found a Bug?
To file a bug or submit a patch, please head over to django-migration-fixer on github.
If you feel generous and want to show some extra appreciation:
Support me with a :star:
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for django-migration-fixer-1.1.1.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | 40e150a639244e1e2f824658c07ef6e1308e3c18e254be0e68a370b778d4a8f9 |
|
MD5 | c9be143445095ba434b149d61a2bd982 |
|
BLAKE2b-256 | a72ab17abef8ff65a6278abdef8c4f83d8c03cfeeb7fc923c23cb692b947f02e |
Hashes for django_migration_fixer-1.1.1-py2.py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 98c473374d307e9a4fd8d8b9a4677cd3b23d3a08f5b4f4a5ada9a2eebecb5442 |
|
MD5 | b0c153280ae856f6796fd214641bf201 |
|
BLAKE2b-256 | 0d08a0280b5dc8cd2a2b1ecc517f996d3f60be6398906ab45086433c3e6293d9 |