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 If you want to include literal percent signs in the query, you have to double
them if you are passing parameters. them if you are passing parameters.
The ``reverse_sql`` queries are executed when the migration is unapplied, so The ``reverse_sql`` queries are executed when the migration is unapplied. They
you can reverse the changes done in the forwards queries:: should undo what is done by the ``sql`` queries. For example, to undo the above
insertion with a deletion::
migrations.RunSQL( migrations.RunSQL(
[("INSERT INTO musician (name) VALUES (%s);", ['Reinhardt'])], sql=[("INSERT INTO musician (name) VALUES (%s);", ['Reinhardt'])],
[("DELETE FROM musician where name=%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 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 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`` 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 The ``reverse_code`` argument is called when unapplying migrations. This
callable should undo what is done in the ``code`` callable so that the 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 The optional ``hints`` argument will be passed as ``**hints`` to the
:meth:`allow_migrate` method of database routers to assist them in making a :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 that your database doesn't match your models, you'll just get errors when
migrations try to modify those tables. 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 Migrations can be reversed with :djadmin:`migrate` by passing the number of the
previous migrations:: previous migration. For example, to reverse migration ``books.0003``:
.. console::
$ python manage.py migrate books 0002 $ python manage.py migrate books 0002
Operations to perform: Operations to perform:
@ -360,8 +364,10 @@ previous migrations::
Rendering model states... DONE Rendering model states... DONE
Unapplying books.0003_auto... OK Unapplying books.0003_auto... OK
If you want to revert all migrations applied for an app, use the name If you want to reverse all migrations applied for an app, use the name
``zero``:: ``zero``:
.. console::
$ python manage.py migrate books zero $ python manage.py migrate books zero
Operations to perform: 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.0002_auto... OK
Unapplying books.0001_initial... 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:
Historical models Historical models