Improved docs on migration reversibility. (#12619)

- Clarify reversibility for RunSQL and RunPython operations.
- Add example for migrate with irreversible migration.

Co-authored-by: Carlton Gibson <carlton.gibson@noumenal.es>
This commit is contained in:
Adam Johnson 2020-03-25 13:37:54 +00:00 committed by GitHub
parent ab5720ad80
commit b15b3706fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 34 additions and 10 deletions

View File

@ -263,14 +263,18 @@ queries and parameters in the same way as :ref:`cursor.execute()
If you want to include literal percent signs in the query, you have to double
them if you are passing parameters.
The ``reverse_sql`` queries are executed when the migration is unapplied, so
you can reverse the changes done in the forwards queries::
The ``reverse_sql`` queries are executed when the migration is unapplied. They
should undo what is done by the ``sql`` queries. For example, to undo the above
insertion with a deletion::
migrations.RunSQL(
[("INSERT INTO musician (name) VALUES (%s);", ['Reinhardt'])],
[("DELETE FROM musician where name=%s;", ['Reinhardt'])],
sql=[("INSERT INTO musician (name) VALUES (%s);", ['Reinhardt'])],
reverse_sql=[("DELETE FROM musician where name=%s;", ['Reinhardt'])],
)
If ``reverse_sql`` is ``None`` (the default), the ``RunSQL`` operation is
irreversible.
The ``state_operations`` argument is so you can supply operations that are
equivalent to the SQL in terms of project state; for example, if you are
manually creating a column, you should pass in a list containing an ``AddField``
@ -317,7 +321,8 @@ instance of :class:`SchemaEditor
The ``reverse_code`` argument is called when unapplying migrations. This
callable should undo what is done in the ``code`` callable so that the
migration is reversible.
migration is reversible. If ``reverse_code`` is ``None`` (the default), the
``RunPython`` operation is irreversible.
The optional ``hints`` argument will be passed as ``**hints`` to the
:meth:`allow_migrate` method of database routers to assist them in making a

View File

@ -347,11 +347,15 @@ Note that this only works given two things:
that your database doesn't match your models, you'll just get errors when
migrations try to modify those tables.
Reverting migrations
.. _reversing-migrations:
Reversing migrations
====================
Any migration can be reverted with :djadmin:`migrate` by using the number of
previous migrations::
Migrations can be reversed with :djadmin:`migrate` by passing the number of the
previous migration. For example, to reverse migration ``books.0003``:
.. console::
$ python manage.py migrate books 0002
Operations to perform:
@ -360,8 +364,10 @@ previous migrations::
Rendering model states... DONE
Unapplying books.0003_auto... OK
If you want to revert all migrations applied for an app, use the name
``zero``::
If you want to reverse all migrations applied for an app, use the name
``zero``:
.. console::
$ python manage.py migrate books zero
Operations to perform:
@ -371,6 +377,19 @@ If you want to revert all migrations applied for an app, use the name
Unapplying books.0002_auto... OK
Unapplying books.0001_initial... OK
A migration is irreversible if it contains any irreversible operations.
Attempting to reverse such migrations will raise ``IrreversibleError``:
.. console::
$ python manage.py migrate books 0002
Operations to perform:
Target specific migration: 0002_auto, from books
Running migrations:
Rendering model states... DONE
Unapplying books.0003_auto...Traceback (most recent call last):
django.db.migrations.exceptions.IrreversibleError: Operation <RunSQL sql='DROP TABLE demo_books'> in books.0003_auto is not reversible
.. _historical-models:
Historical models