Metadata-Version: 2.1
Name: django-migrate-or-rollback
Version: 0.0.2
Summary: Management command to attempt Django migrations and rollback on failure
Home-page: https://github.com/zagaran/django-migrate-or-rollback
Author: Zagaran, Inc.
Author-email: info@zagaran.com
License: MIT
Keywords: django migrations
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.6
Description-Content-Type: text/markdown
License-File: LICENSE

# django-migrate-or-rollback

While single migrations in Django are atomic (as long as they have the default `atomic=True`),
a group of migrations are not.  Thus, when running migrations, you can have a partial
failure where some but not all of your migrations succeed.  This library fixes that.

This library provides a new management command `migrate_or_rollback`.  It's a drop-in
replacement for the Django builtin management command `migrate`.  Here's how it works:

1. Checks your database and current migration files for the latest migrations run per Django app.
2. Runs migrations as normal.
3. If migrations fail, it rolls back to the migrations identified in step 1.

## Instalation

`pip install django-migrate-or-rollback`

Alternatively, add `django-migrate-or-rollback` to your requirements.txt file.

Then, add `"django_migrate_or_rollback"` to your `INSTALLED_APPS` in settings.py, like so:

```
# settings.py
INSTALLED_APPS = [
    # ...
    "django_migrate_or_rollback",
]
```

## Usage

Run `python manage.py migrate_or_rollback` instead of the standard `migrate` command.

In particular, you should use `migrate_or_rollback` in place of `migrate` in your deployment scripts or CI/CD system.

`migrate_or_rollback` has all of the same options as `migrate`, such as the `--noinput` flag.


## Warning

This library assumes that your migrations are reversable.  Not all migrations are reversible.  Additionally, rolling back migrations only reverses schema doesn't rewind the database contents.

In particular:
* Deleted data (such as dropping columns or tables) won't be restored by rolling
back the migration that deletes it.  To avoid this, you should make fields
nullable in one deploy and delete them in the next.
* `RunPython` statements that are missing a `reverse` function will error on
rollback.  At a minimum, add `migrations.RunPython.noop` as a reverse function.
Additionally, RunPython reverse functions can be used to rewind changes to
database contents on migration rollback.
* A migration that deletes a non-nullable field will error on rollback.
To avoid this, make the field nullable in one deploy and delete it in the next.

