mirror of https://github.com/django/django.git
Improved formatting and links of migration docs.
This commit is contained in:
parent
8905fcbda6
commit
ab8d8e00c9
|
@ -2,39 +2,39 @@
|
||||||
Migration Operations
|
Migration Operations
|
||||||
====================
|
====================
|
||||||
|
|
||||||
Migration files are composed of one or more Operations, objects that
|
.. module:: django.db.migrations.operations
|
||||||
|
|
||||||
|
Migration files are composed of one or more ``Operation``\s, objects that
|
||||||
declaratively record what the migration should do to your database.
|
declaratively record what the migration should do to your database.
|
||||||
|
|
||||||
Django also uses these Operation objects to work out what your models
|
Django also uses these ``Operation`` objects to work out what your models
|
||||||
looked like historically, and to calculate what changes you've made to
|
looked like historically, and to calculate what changes you've made to
|
||||||
your models since the last migration so it can automatically write
|
your models since the last migration so it can automatically write
|
||||||
your migrations; that's why they're declarative, as it means Django can
|
your migrations; that's why they're declarative, as it means Django can
|
||||||
easily load them all into memory and run through them without touching
|
easily load them all into memory and run through them without touching
|
||||||
the database to work out what your project should look like.
|
the database to work out what your project should look like.
|
||||||
|
|
||||||
There are also more specialized Operation objects which are for things like
|
There are also more specialized ``Operation`` objects which are for things like
|
||||||
:ref:`data migrations <data-migrations>` and for advanced manual database
|
:ref:`data migrations <data-migrations>` and for advanced manual database
|
||||||
manipulation. You can also write your own Operation classes if you want
|
manipulation. You can also write your own ``Operation`` classes if you want
|
||||||
to encapsulate a custom change you commonly make.
|
to encapsulate a custom change you commonly make.
|
||||||
|
|
||||||
If you need an empty migration file to write your own Operation objects
|
If you need an empty migration file to write your own ``Operation`` objects
|
||||||
into, just use ``python manage.py makemigrations --empty yourappname``,
|
into, just use ``python manage.py makemigrations --empty yourappname``,
|
||||||
but be aware that manually adding schema-altering operations can confuse the
|
but be aware that manually adding schema-altering operations can confuse the
|
||||||
migration autodetector and make resulting runs of ``makemigrations`` output
|
migration autodetector and make resulting runs of :djadmin:`makemigrations`
|
||||||
incorrect code.
|
output incorrect code.
|
||||||
|
|
||||||
All of the core Django operations are available from the
|
All of the core Django operations are available from the
|
||||||
``django.db.migrations.operations`` module.
|
``django.db.migrations.operations`` module.
|
||||||
|
|
||||||
|
|
||||||
Schema Operations
|
Schema Operations
|
||||||
=================
|
=================
|
||||||
|
|
||||||
CreateModel
|
CreateModel
|
||||||
-----------
|
-----------
|
||||||
::
|
|
||||||
|
|
||||||
CreateModel(name, fields, options=None, bases=None)
|
.. class:: CreateModel(name, fields, options=None, bases=None)
|
||||||
|
|
||||||
Creates a new model in the project history and a corresponding table in the
|
Creates a new model in the project history and a corresponding table in the
|
||||||
database to match it.
|
database to match it.
|
||||||
|
@ -53,21 +53,17 @@ it can contain both class objects as well as strings in the format
|
||||||
from the historical version). If it's not supplied, it defaults to just
|
from the historical version). If it's not supplied, it defaults to just
|
||||||
inheriting from the standard ``models.Model``.
|
inheriting from the standard ``models.Model``.
|
||||||
|
|
||||||
|
|
||||||
DeleteModel
|
DeleteModel
|
||||||
-----------
|
-----------
|
||||||
::
|
|
||||||
|
|
||||||
DeleteModel(name)
|
.. class:: DeleteModel(name)
|
||||||
|
|
||||||
Deletes the model from the project history and its table from the database.
|
Deletes the model from the project history and its table from the database.
|
||||||
|
|
||||||
|
|
||||||
RenameModel
|
RenameModel
|
||||||
-----------
|
-----------
|
||||||
::
|
|
||||||
|
|
||||||
RenameModel(old_name, new_name)
|
.. class:: RenameModel(old_name, new_name)
|
||||||
|
|
||||||
Renames the model from an old name to a new one.
|
Renames the model from an old name to a new one.
|
||||||
|
|
||||||
|
@ -77,41 +73,36 @@ the autodetector, this will look like you deleted a model with the old name
|
||||||
and added a new one with a different name, and the migration it creates will
|
and added a new one with a different name, and the migration it creates will
|
||||||
lose any data in the old table.
|
lose any data in the old table.
|
||||||
|
|
||||||
|
|
||||||
AlterModelTable
|
AlterModelTable
|
||||||
---------------
|
---------------
|
||||||
::
|
|
||||||
|
|
||||||
AlterModelTable(name, table)
|
.. class:: AlterModelTable(name, table)
|
||||||
|
|
||||||
Changes the model's table name (the ``db_table`` option on the ``Meta`` subclass)
|
|
||||||
|
|
||||||
|
Changes the model's table name (the :attr:`~django.db.models.Options.db_table`
|
||||||
|
option on the ``Meta`` subclass).
|
||||||
|
|
||||||
AlterUniqueTogether
|
AlterUniqueTogether
|
||||||
-------------------
|
-------------------
|
||||||
::
|
|
||||||
|
|
||||||
AlterUniqueTogether(name, unique_together)
|
.. class:: AlterUniqueTogether(name, unique_together)
|
||||||
|
|
||||||
Changes the model's set of unique constraints
|
|
||||||
(the ``unique_together`` option on the ``Meta`` subclass)
|
|
||||||
|
|
||||||
|
Changes the model's set of unique constraints (the
|
||||||
|
:attr:`~django.db.models.Options.unique_together` option on the ``Meta``
|
||||||
|
subclass).
|
||||||
|
|
||||||
AlterIndexTogether
|
AlterIndexTogether
|
||||||
------------------
|
------------------
|
||||||
::
|
|
||||||
|
|
||||||
AlterIndexTogether(name, index_together)
|
.. class:: AlterIndexTogether(name, index_together)
|
||||||
|
|
||||||
Changes the model's set of custom indexes
|
|
||||||
(the ``index_together`` option on the ``Meta`` subclass)
|
|
||||||
|
|
||||||
|
Changes the model's set of custom indexes (the
|
||||||
|
:attr:`~django.db.models.Options.index_together` option on the ``Meta``
|
||||||
|
subclass).
|
||||||
|
|
||||||
AddField
|
AddField
|
||||||
--------
|
--------
|
||||||
::
|
|
||||||
|
|
||||||
AddField(model_name, name, field, preserve_default=True)
|
.. class:: AddField(model_name, name, field, preserve_default=True)
|
||||||
|
|
||||||
Adds a field to a model. ``model_name`` is the model's name, ``name`` is
|
Adds a field to a model. ``model_name`` is the model's name, ``name`` is
|
||||||
the field's name, and ``field`` is an unbound Field instance (the thing
|
the field's name, and ``field`` is an unbound Field instance (the thing
|
||||||
|
@ -126,12 +117,10 @@ a default value to put into existing rows. It does not effect the behavior
|
||||||
of setting defaults in the database directly - Django never sets database
|
of setting defaults in the database directly - Django never sets database
|
||||||
defaults, and always applies them in the Django ORM code.
|
defaults, and always applies them in the Django ORM code.
|
||||||
|
|
||||||
|
|
||||||
RemoveField
|
RemoveField
|
||||||
-----------
|
-----------
|
||||||
::
|
|
||||||
|
|
||||||
RemoveField(model_name, name)
|
.. class:: RemoveField(model_name, name)
|
||||||
|
|
||||||
Removes a field from a model.
|
Removes a field from a model.
|
||||||
|
|
||||||
|
@ -139,42 +128,34 @@ Bear in mind that when reversed this is actually adding a field to a model;
|
||||||
if the field is not nullable this may make this operation irreversible (apart
|
if the field is not nullable this may make this operation irreversible (apart
|
||||||
from any data loss, which of course is irreversible).
|
from any data loss, which of course is irreversible).
|
||||||
|
|
||||||
|
|
||||||
AlterField
|
AlterField
|
||||||
----------
|
----------
|
||||||
::
|
|
||||||
|
|
||||||
AlterField(model_name, name, field)
|
.. class:: AlterField(model_name, name, field)
|
||||||
|
|
||||||
Alters a field's definition, including changes to its type, ``null``, ``unique``,
|
Alters a field's definition, including changes to its type,
|
||||||
``db_column`` and other field attributes.
|
:attr:`~django.db.models.Field.null`, :attr:`~django.db.models.Field.unique`,
|
||||||
|
:attr:`~django.db.models.Field.db_column` and other field attributes.
|
||||||
|
|
||||||
Note that not all changes are possible on all databases - for example, you
|
Note that not all changes are possible on all databases - for example, you
|
||||||
cannot change a text-type field like ``models.TextField()`` into a number-type
|
cannot change a text-type field like ``models.TextField()`` into a number-type
|
||||||
field like ``models.IntegerField()`` on most databases.
|
field like ``models.IntegerField()`` on most databases.
|
||||||
|
|
||||||
|
|
||||||
RenameField
|
RenameField
|
||||||
-----------
|
-----------
|
||||||
::
|
|
||||||
|
|
||||||
RenameField(model_name, old_name, new_name)
|
|
||||||
|
|
||||||
Changes a field's name (and, unless ``db_column`` is set, its column name).
|
|
||||||
|
|
||||||
|
.. class:: RenameField(model_name, old_name, new_name)
|
||||||
|
|
||||||
|
Changes a field's name (and, unless :attr:`~django.db.models.Field.db_column`
|
||||||
|
is set, its column name).
|
||||||
|
|
||||||
Special Operations
|
Special Operations
|
||||||
==================
|
==================
|
||||||
|
|
||||||
.. _operation-run-sql:
|
|
||||||
|
|
||||||
RunSQL
|
RunSQL
|
||||||
------
|
------
|
||||||
|
|
||||||
::
|
.. class:: RunSQL(sql, reverse_sql=None, state_operations=None)
|
||||||
|
|
||||||
RunSQL(sql, reverse_sql=None, state_operations=None)
|
|
||||||
|
|
||||||
Allows running of arbitrary SQL on the database - useful for more advanced
|
Allows running of arbitrary SQL on the database - useful for more advanced
|
||||||
features of database backends that Django doesn't support directly, like
|
features of database backends that Django doesn't support directly, like
|
||||||
|
@ -194,24 +175,22 @@ operation that adds that field and so will try to run it again).
|
||||||
|
|
||||||
.. _sqlparse: https://pypi.python.org/pypi/sqlparse
|
.. _sqlparse: https://pypi.python.org/pypi/sqlparse
|
||||||
|
|
||||||
.. _operation-run-python:
|
|
||||||
|
|
||||||
RunPython
|
RunPython
|
||||||
---------
|
---------
|
||||||
|
|
||||||
::
|
.. class:: RunPython(code, reverse_code=None)
|
||||||
|
|
||||||
RunPython(code, reverse_code=None)
|
|
||||||
|
|
||||||
Runs custom Python code in a historical context. ``code`` (and ``reverse_code``
|
Runs custom Python code in a historical context. ``code`` (and ``reverse_code``
|
||||||
if supplied) should be callable objects that accept two arguments; the first is
|
if supplied) should be callable objects that accept two arguments; the first is
|
||||||
an instance of ``django.apps.registry.Apps`` containing historical models that
|
an instance of ``django.apps.registry.Apps`` containing historical models that
|
||||||
match the operation's place in the project history, and the second is an
|
match the operation's place in the project history, and the second is an
|
||||||
instance of SchemaEditor.
|
instance of :class:`SchemaEditor
|
||||||
|
<django.db.backends.schema.BaseDatabaseSchemaEditor>`.
|
||||||
|
|
||||||
You are advised to write the code as a separate function above the ``Migration``
|
You are advised to write the code as a separate function above the ``Migration``
|
||||||
class in the migration file, and just pass it to ``RunPython``. Here's an
|
class in the migration file, and just pass it to ``RunPython``. Here's an
|
||||||
example of using RunPython to create some initial objects on a Country model::
|
example of using ``RunPython`` to create some initial objects on a ``Country``
|
||||||
|
model::
|
||||||
|
|
||||||
# encoding: utf8
|
# encoding: utf8
|
||||||
from django.db import models, migrations
|
from django.db import models, migrations
|
||||||
|
@ -245,19 +224,16 @@ or ``orm["appname", "Model"]`` references from South directly into
|
||||||
``apps.get_model("appname", "Model")`` references here and leave most of the
|
``apps.get_model("appname", "Model")`` references here and leave most of the
|
||||||
rest of the code unchanged for data migrations.
|
rest of the code unchanged for data migrations.
|
||||||
|
|
||||||
Much like ``RunSQL``, ensure that if you change schema inside here you're
|
Much like :class:`RunSQL`, ensure that if you change schema inside here you're
|
||||||
either doing it outside the scope of the Django model system (e.g. triggers)
|
either doing it outside the scope of the Django model system (e.g. triggers)
|
||||||
or that you use ``SeparateDatabaseAndState`` to add in operations that will
|
or that you use :class:`SeparateDatabaseAndState` to add in operations that will
|
||||||
reflect your changes to the model state - otherwise, the versioned ORM and
|
reflect your changes to the model state - otherwise, the versioned ORM and
|
||||||
the autodetector will stop working correctly.
|
the autodetector will stop working correctly.
|
||||||
|
|
||||||
|
|
||||||
SeparateDatabaseAndState
|
SeparateDatabaseAndState
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
::
|
.. class:: SeparateDatabaseAndState(database_operations=None, state_operations=None)
|
||||||
|
|
||||||
SeparateDatabaseAndState(database_operations=None, state_operations=None)
|
|
||||||
|
|
||||||
A highly specialized operation that let you mix and match the database
|
A highly specialized operation that let you mix and match the database
|
||||||
(schema-changing) and state (autodetector-powering) aspects of operations.
|
(schema-changing) and state (autodetector-powering) aspects of operations.
|
||||||
|
@ -266,13 +242,12 @@ It accepts two list of operations, and when asked to apply state will use the
|
||||||
state list, and when asked to apply changes to the database will use the database
|
state list, and when asked to apply changes to the database will use the database
|
||||||
list. Do not use this operation unless you're very sure you know what you're doing.
|
list. Do not use this operation unless you're very sure you know what you're doing.
|
||||||
|
|
||||||
|
|
||||||
Writing your own
|
Writing your own
|
||||||
================
|
================
|
||||||
|
|
||||||
Operations have a relatively simple API, and they're designed so that you can
|
Operations have a relatively simple API, and they're designed so that you can
|
||||||
easily write your own to supplement the built-in Django ones. The basic structure
|
easily write your own to supplement the built-in Django ones. The basic structure
|
||||||
of an Operation looks like this::
|
of an ``Operation`` looks like this::
|
||||||
|
|
||||||
from django.db.migrations.operations.base import Operation
|
from django.db.migrations.operations.base import Operation
|
||||||
|
|
||||||
|
@ -317,7 +292,7 @@ historical models.
|
||||||
|
|
||||||
Some things to note:
|
Some things to note:
|
||||||
|
|
||||||
* You don't need to learn too much about ProjectState to just write simple
|
* You don't need to learn too much about ``ProjectState`` to just write simple
|
||||||
migrations; just know that it has a ``.render()`` method that turns it into
|
migrations; just know that it has a ``.render()`` method that turns it into
|
||||||
an app registry (which you can then call ``get_model`` on).
|
an app registry (which you can then call ``get_model`` on).
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
============
|
================
|
||||||
SchemaEditor
|
``SchemaEditor``
|
||||||
============
|
================
|
||||||
|
|
||||||
|
.. module:: django.db.backends.schema
|
||||||
|
|
||||||
|
.. class:: BaseDatabaseSchemaEditor
|
||||||
|
|
||||||
Django's migration system is split into two parts; the logic for calculating
|
Django's migration system is split into two parts; the logic for calculating
|
||||||
and storing what operations should be run (``django.db.migrations``), and the
|
and storing what operations should be run (``django.db.migrations``), and the
|
||||||
|
@ -27,10 +31,10 @@ of change are not possible on all databases - for example, MyISAM does not
|
||||||
support foreign key constraints.
|
support foreign key constraints.
|
||||||
|
|
||||||
If you are writing or maintaining a third-party database backend for Django,
|
If you are writing or maintaining a third-party database backend for Django,
|
||||||
you will need to provide a SchemaEditor implementation in order to work with
|
you will need to provide a ``SchemaEditor`` implementation in order to work with
|
||||||
1.7's migration functionality - however, as long as your database is relatively
|
1.7's migration functionality - however, as long as your database is relatively
|
||||||
standard in its use of SQL and relational design, you should be able to
|
standard in its use of SQL and relational design, you should be able to
|
||||||
subclass one of the built-in Django SchemaEditor classes and just tweak the
|
subclass one of the built-in Django ``SchemaEditor`` classes and just tweak the
|
||||||
syntax a little. Also note that there are a few new database features that
|
syntax a little. Also note that there are a few new database features that
|
||||||
migrations will look for: ``can_rollback_ddl`` and
|
migrations will look for: ``can_rollback_ddl`` and
|
||||||
``supports_combined_alters`` are the most important.
|
``supports_combined_alters`` are the most important.
|
||||||
|
@ -41,9 +45,7 @@ Methods
|
||||||
execute
|
execute
|
||||||
-------
|
-------
|
||||||
|
|
||||||
::
|
.. method:: BaseDatabaseSchemaEditor.execute(sql, params=[])
|
||||||
|
|
||||||
execute(sql, params=[])
|
|
||||||
|
|
||||||
Executes the SQL statement passed in, with parameters if supplied. This
|
Executes the SQL statement passed in, with parameters if supplied. This
|
||||||
is a simple wrapper around the normal database cursors that allows
|
is a simple wrapper around the normal database cursors that allows
|
||||||
|
@ -52,92 +54,71 @@ capture of the SQL to a ``.sql`` file if the user wishes.
|
||||||
create_model
|
create_model
|
||||||
------------
|
------------
|
||||||
|
|
||||||
::
|
.. method:: BaseDatabaseSchemaEditor.create_model(model)
|
||||||
|
|
||||||
create_model(model)
|
|
||||||
|
|
||||||
Creates a new table in the database for the provided model, along with any
|
Creates a new table in the database for the provided model, along with any
|
||||||
unique constraints or indexes it requires.
|
unique constraints or indexes it requires.
|
||||||
|
|
||||||
|
|
||||||
delete_model
|
delete_model
|
||||||
------------
|
------------
|
||||||
|
|
||||||
::
|
.. method:: BaseDatabaseSchemaEditor.delete_model(model)
|
||||||
|
|
||||||
delete_model(model)
|
|
||||||
|
|
||||||
Drops the model's table in the database along with any unique constraints
|
Drops the model's table in the database along with any unique constraints
|
||||||
or indexes it has.
|
or indexes it has.
|
||||||
|
|
||||||
|
|
||||||
alter_unique_together
|
alter_unique_together
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
::
|
.. method:: BaseDatabaseSchemaEditor.alter_unique_together(model, old_unique_together, new_unique_together)
|
||||||
|
|
||||||
alter_unique_together(model, old_unique_together, new_unique_together)
|
|
||||||
|
|
||||||
Changes a model's unique_together value; this will add or remove unique
|
|
||||||
constraints from the model's table until they match the new value.
|
|
||||||
|
|
||||||
|
Changes a model's :attr:`~django.db.models.Options.unique_together` value; this
|
||||||
|
will add or remove unique constraints from the model's table until they match
|
||||||
|
the new value.
|
||||||
|
|
||||||
alter_index_together
|
alter_index_together
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
::
|
.. method:: BaseDatabaseSchemaEditor.alter_index_together(model, old_index_together, new_index_together)
|
||||||
|
|
||||||
alter_index_together(model, old_index_together, new_index_together)
|
|
||||||
|
|
||||||
Changes a model's index_together value; this will add or remove indexes
|
|
||||||
from the model's table until they match the new value.
|
|
||||||
|
|
||||||
|
Changes a model's :attr:`~django.db.models.Options.index_together` value; this
|
||||||
|
will add or remove indexes from the model's table until they match the new
|
||||||
|
value.
|
||||||
|
|
||||||
alter_db_table
|
alter_db_table
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
::
|
.. method:: BaseDatabaseSchemaEditor.alter_db_table(model, old_db_table, new_db_table)
|
||||||
|
|
||||||
alter_db_table(model, old_db_table, new_db_table)
|
|
||||||
|
|
||||||
Renames the model's table from ``old_db_table`` to ``new_db_table``.
|
Renames the model's table from ``old_db_table`` to ``new_db_table``.
|
||||||
|
|
||||||
|
|
||||||
alter_db_tablespace
|
alter_db_tablespace
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
::
|
.. method:: BaseDatabaseSchemaEditor.alter_db_tablespace(model, old_db_tablespace, new_db_tablespace)
|
||||||
|
|
||||||
alter_db_tablespace(model, old_db_tablespace, new_db_tablespace)
|
|
||||||
|
|
||||||
Moves the model's table from one tablespace to another.
|
Moves the model's table from one tablespace to another.
|
||||||
|
|
||||||
|
|
||||||
add_field
|
add_field
|
||||||
---------
|
---------
|
||||||
|
|
||||||
::
|
.. method:: BaseDatabaseSchemaEditor.add_field(model, field)
|
||||||
|
|
||||||
add_field(model, field)
|
|
||||||
|
|
||||||
Adds a column (or sometimes multiple) to the model's table to represent the
|
Adds a column (or sometimes multiple) to the model's table to represent the
|
||||||
field. This will also add indexes or a unique constraint
|
field. This will also add indexes or a unique constraint
|
||||||
if the field has ``db_index=True`` or ``unique=True``.
|
if the field has ``db_index=True`` or ``unique=True``.
|
||||||
|
|
||||||
If the field is a ManyToManyField without a value for ``through``, instead of
|
If the field is a ``ManyToManyField`` without a value for ``through``, instead
|
||||||
creating a column, it will make a table to represent the relationship. If
|
of creating a column, it will make a table to represent the relationship. If
|
||||||
``through`` is provided, it is a no-op.
|
``through`` is provided, it is a no-op.
|
||||||
|
|
||||||
If the field is a ``ForeignKey``, this will also add the foreign key
|
If the field is a ``ForeignKey``, this will also add the foreign key
|
||||||
constraint to the column.
|
constraint to the column.
|
||||||
|
|
||||||
|
|
||||||
remove_field
|
remove_field
|
||||||
------------
|
------------
|
||||||
|
|
||||||
::
|
.. method:: BaseDatabaseSchemaEditor.remove_field(model, field)
|
||||||
|
|
||||||
remove_field(model, field)
|
|
||||||
|
|
||||||
Removes the column(s) representing the field from the model's table, along
|
Removes the column(s) representing the field from the model's table, along
|
||||||
with any unique constraints, foreign key constraints, or indexes caused by
|
with any unique constraints, foreign key constraints, or indexes caused by
|
||||||
|
@ -147,25 +128,22 @@ If the field is a ManyToManyField without a value for ``through``, it will
|
||||||
remove the table created to track the relationship. If
|
remove the table created to track the relationship. If
|
||||||
``through`` is provided, it is a no-op.
|
``through`` is provided, it is a no-op.
|
||||||
|
|
||||||
|
|
||||||
alter_field
|
alter_field
|
||||||
------------
|
------------
|
||||||
|
|
||||||
::
|
.. method:: BaseDatabaseSchemaEditor.alter_field(model, old_field, new_field, strict=False)
|
||||||
|
|
||||||
alter_field(model, old_field, new_field, strict=False)
|
|
||||||
|
|
||||||
This transforms the field on the model from the old field to the new one. This
|
This transforms the field on the model from the old field to the new one. This
|
||||||
includes changing the name of the column (the ``db_column`` attribute),
|
includes changing the name of the column (the
|
||||||
changing the type of the field (if the field class changes), changing
|
:attr:`~django.db.models.Field.db_column` attribute), changing the type of the
|
||||||
the ``NULL`` status of the field, adding or removing field-only unique
|
field (if the field class changes), changing the ``NULL`` status of the field,
|
||||||
constraints and indexes, changing primary key, and changing the destination
|
adding or removing field-only unique constraints and indexes, changing primary
|
||||||
of ForeignKey constraints.
|
key, and changing the destination of ``ForeignKey`` constraints.
|
||||||
|
|
||||||
The most common transformation this cannot do is transforming a
|
The most common transformation this cannot do is transforming a
|
||||||
ManyToManyField into a normal Field or vice-versa; Django cannot do this
|
``ManyToManyField`` into a normal Field or vice-versa; Django cannot do this
|
||||||
without losing data, and so it will refuse to do it. Instead, ``remove_field``
|
without losing data, and so it will refuse to do it. Instead,
|
||||||
and ``add_field`` should be called separately.
|
:meth:`.remove_field` and :meth:`.add_field` should be called separately.
|
||||||
|
|
||||||
If the database has the ``supports_combined_alters``, Django will try and
|
If the database has the ``supports_combined_alters``, Django will try and
|
||||||
do as many of these in a single database call as possible; otherwise, it will
|
do as many of these in a single database call as possible; otherwise, it will
|
||||||
|
|
|
@ -639,8 +639,9 @@ Management Commands
|
||||||
* :ref:`initial-sql` now works better if the sqlparse_ Python library is
|
* :ref:`initial-sql` now works better if the sqlparse_ Python library is
|
||||||
installed.
|
installed.
|
||||||
|
|
||||||
Note that it's deprecated in favor of the :ref:`RunSQL <operation-run-sql>`
|
Note that it's deprecated in favor of the
|
||||||
operation of migrations, which benefits from the improved behavior.
|
:class:`~django.db.migrations.operations.RunSQL` operation of migrations,
|
||||||
|
which benefits from the improved behavior.
|
||||||
|
|
||||||
.. _sqlparse: https://pypi.python.org/pypi/sqlparse
|
.. _sqlparse: https://pypi.python.org/pypi/sqlparse
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ A Brief History
|
||||||
|
|
||||||
Prior to version 1.7, Django only supported adding new models to the
|
Prior to version 1.7, Django only supported adding new models to the
|
||||||
database; it was not possible to alter or remove existing models via the
|
database; it was not possible to alter or remove existing models via the
|
||||||
``syncdb`` command (the predecessor to ``migrate``).
|
``syncdb`` command (the predecessor to :djadmin:`migrate`).
|
||||||
|
|
||||||
Third-party tools, most notably `South <http://south.aeracode.org>`_,
|
Third-party tools, most notably `South <http://south.aeracode.org>`_,
|
||||||
provided support for these additional types of change, but it was considered
|
provided support for these additional types of change, but it was considered
|
||||||
|
@ -53,7 +53,8 @@ staging machines, and eventually your production machines.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
It is possible to override the name of the package which contains the
|
It is possible to override the name of the package which contains the
|
||||||
migrations on a per-app basis by modifying the :setting:`MIGRATION_MODULES` setting.
|
migrations on a per-app basis by modifying the :setting:`MIGRATION_MODULES`
|
||||||
|
setting.
|
||||||
|
|
||||||
Migrations will run the same way on the same dataset and produce consistent
|
Migrations will run the same way on the same dataset and produce consistent
|
||||||
results, meaning that what you see in development and staging is, under the
|
results, meaning that what you see in development and staging is, under the
|
||||||
|
@ -184,14 +185,14 @@ Dependencies
|
||||||
While migrations are per-app, the tables and relationships implied by
|
While migrations are per-app, the tables and relationships implied by
|
||||||
your models are too complex to be created for just one app at a time. When
|
your models are too complex to be created for just one app at a time. When
|
||||||
you make a migration that requires something else to run - for example,
|
you make a migration that requires something else to run - for example,
|
||||||
you add a ForeignKey in your ``books`` app to your ``authors`` app - the
|
you add a ``ForeignKey`` in your ``books`` app to your ``authors`` app - the
|
||||||
resulting migration will contain a dependency on a migration in ``authors``.
|
resulting migration will contain a dependency on a migration in ``authors``.
|
||||||
|
|
||||||
This means that when you run the migrations, the ``authors`` migration runs
|
This means that when you run the migrations, the ``authors`` migration runs
|
||||||
first and creates the table the ``ForeignKey`` references, and then the migration
|
first and creates the table the ``ForeignKey`` references, and then the migration
|
||||||
that makes the ``ForeignKey`` column runs afterwards and creates the constraint.
|
that makes the ``ForeignKey`` column runs afterwards and creates the constraint.
|
||||||
If this didn't happen, the migration would try to create the ForeignKey column
|
If this didn't happen, the migration would try to create the ``ForeignKey``
|
||||||
without the table it's referencing existing and your database would
|
column without the table it's referencing existing and your database would
|
||||||
throw an error.
|
throw an error.
|
||||||
|
|
||||||
This dependency behavior affects most migration operations where you
|
This dependency behavior affects most migration operations where you
|
||||||
|
@ -228,8 +229,8 @@ inspects this object for four attributes, only two of which are used
|
||||||
most of the time:
|
most of the time:
|
||||||
|
|
||||||
* ``dependencies``, a list of migrations this one depends on.
|
* ``dependencies``, a list of migrations this one depends on.
|
||||||
* ``operations``, a list of Operation classes that define what this migration
|
* ``operations``, a list of ``Operation`` classes that define what this
|
||||||
does.
|
migration does.
|
||||||
|
|
||||||
The operations are the key; they are a set of declarative instructions which
|
The operations are the key; they are a set of declarative instructions which
|
||||||
tell Django what schema changes need to be made. Django scans them and
|
tell Django what schema changes need to be made. Django scans them and
|
||||||
|
@ -252,9 +253,9 @@ Custom fields
|
||||||
~~~~~~~~~~~~~
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
You can't modify the number of positional arguments in an already migrated
|
You can't modify the number of positional arguments in an already migrated
|
||||||
custom field without raising a TypeError. The old migration will call the
|
custom field without raising a ``TypeError``. The old migration will call the
|
||||||
modified ``__init__`` method with the old signature. So if you need a new
|
modified ``__init__`` method with the old signature. So if you need a new
|
||||||
argument, please create a keyword argument and use e.g.
|
argument, please create a keyword argument and add something like
|
||||||
``assert kwargs.get('argument_name') is not None`` in the constructor.
|
``assert kwargs.get('argument_name') is not None`` in the constructor.
|
||||||
|
|
||||||
Adding migrations to apps
|
Adding migrations to apps
|
||||||
|
@ -285,7 +286,6 @@ 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.
|
||||||
|
|
||||||
|
|
||||||
.. _historical-models:
|
.. _historical-models:
|
||||||
|
|
||||||
Historical models
|
Historical models
|
||||||
|
@ -293,9 +293,9 @@ Historical models
|
||||||
|
|
||||||
When you run migrations, Django is working from historical versions of
|
When you run migrations, Django is working from historical versions of
|
||||||
your models stored in the migration files. If you write Python code
|
your models stored in the migration files. If you write Python code
|
||||||
using the ``django.db.migrations.RunPython`` operation, or if you have
|
using the :class:`~django.db.migrations.operations.RunPython` operation, or if
|
||||||
``allow_migrate`` methods on your database routers, you will be exposed
|
you have ``allow_migrate`` methods on your database routers, you will be
|
||||||
to these versions of your models.
|
exposed to these versions of your models.
|
||||||
|
|
||||||
Because it's impossible to serialize arbitrary Python code, these historical
|
Because it's impossible to serialize arbitrary Python code, these historical
|
||||||
models will not have any custom methods or managers that you have defined.
|
models will not have any custom methods or managers that you have defined.
|
||||||
|
@ -304,9 +304,9 @@ They will, however, have the same fields, relationships and ``Meta`` options
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
|
|
||||||
This means that you will NOT have custom save() methods called on objects
|
This means that you will NOT have custom ``save()`` methods called on objects
|
||||||
when you access them in migrations, and you will NOT have any custom constructors
|
when you access them in migrations, and you will NOT have any custom
|
||||||
or instance methods. Plan appropriately!
|
constructors or instance methods. Plan appropriately!
|
||||||
|
|
||||||
In addition, the base classes of the model are just stored as pointers,
|
In addition, the base classes of the model are just stored as pointers,
|
||||||
so you must always keep base classes around for as long as there is a migration
|
so you must always keep base classes around for as long as there is a migration
|
||||||
|
@ -314,7 +314,6 @@ that contains a reference to them. On the plus side, methods and managers
|
||||||
from these base classes inherit normally, so if you absolutely need access
|
from these base classes inherit normally, so if you absolutely need access
|
||||||
to these you can opt to move them into a superclass.
|
to these you can opt to move them into a superclass.
|
||||||
|
|
||||||
|
|
||||||
.. _data-migrations:
|
.. _data-migrations:
|
||||||
|
|
||||||
Data Migrations
|
Data Migrations
|
||||||
|
@ -330,7 +329,7 @@ Django can't automatically generate data migrations for you, as it does with
|
||||||
schema migrations, but it's not very hard to write them. Migration files in
|
schema migrations, but it's not very hard to write them. Migration files in
|
||||||
Django are made up of :doc:`Operations </ref/migration-operations>`, and
|
Django are made up of :doc:`Operations </ref/migration-operations>`, and
|
||||||
the main operation you use for data migrations is
|
the main operation you use for data migrations is
|
||||||
:ref:`RunPython <operation-run-python>`.
|
:class:`~django.db.migrations.operations.RunPython`.
|
||||||
|
|
||||||
To start, make an empty migration file you can work from (Django will put
|
To start, make an empty migration file you can work from (Django will put
|
||||||
the file in the right place, suggest a name, and add dependencies for you)::
|
the file in the right place, suggest a name, and add dependencies for you)::
|
||||||
|
@ -351,13 +350,15 @@ Then, open up the file; it should look something like this::
|
||||||
operations = [
|
operations = [
|
||||||
]
|
]
|
||||||
|
|
||||||
Now, all you need to do is create a new function and have RunPython use it.
|
Now, all you need to do is create a new function and have
|
||||||
RunPython expects a callable as its argument which takes two arguments - the
|
:class:`~django.db.migrations.operations.RunPython` use it.
|
||||||
first is an :doc:`app registry </ref/applications/>` that has the historical
|
:class:`~django.db.migrations.operations.RunPython` expects a callable as its argument
|
||||||
versions of all your models loaded into it to match where in your history the
|
which takes two arguments - the first is an :doc:`app registry
|
||||||
migration sits, and the second is a :doc:`SchemaEditor </ref/schema-editor>`,
|
</ref/applications/>` that has the historical versions of all your models
|
||||||
which you can use to manually effect database schema changes (but beware,
|
loaded into it to match where in your history the migration sits, and the
|
||||||
doing this can confuse the migration autodetector!)
|
second is a :doc:`SchemaEditor </ref/schema-editor>`, which you can use to
|
||||||
|
manually effect database schema changes (but beware, doing this can confuse
|
||||||
|
the migration autodetector!)
|
||||||
|
|
||||||
Let's write a simple migration that populates our new ``name`` field with the
|
Let's write a simple migration that populates our new ``name`` field with the
|
||||||
combined values of ``first_name`` and ``last_name`` (we've come to our senses
|
combined values of ``first_name`` and ``last_name`` (we've come to our senses
|
||||||
|
@ -389,8 +390,8 @@ Once that's done, we can just run ``python manage.py migrate`` as normal and
|
||||||
the data migration will run in place alongside other migrations.
|
the data migration will run in place alongside other migrations.
|
||||||
|
|
||||||
If you're interested in the more advanced migration operations, or want
|
If you're interested in the more advanced migration operations, or want
|
||||||
to be able to write your own, see our
|
to be able to write your own, see the :doc:`migration operations reference
|
||||||
:doc:`migration operations reference </ref/migration-operations>`.
|
</ref/migration-operations>`.
|
||||||
|
|
||||||
.. _migration-squashing:
|
.. _migration-squashing:
|
||||||
|
|
||||||
|
@ -406,15 +407,19 @@ Squashing is the act of reducing an existing set of many migrations down to
|
||||||
one (or sometimes a few) migrations which still represent the same changes.
|
one (or sometimes a few) migrations which still represent the same changes.
|
||||||
|
|
||||||
Django does this by taking all of your existing migrations, extracting their
|
Django does this by taking all of your existing migrations, extracting their
|
||||||
Operations and putting them all in sequence, and then running an optimizer
|
``Operation``\s and putting them all in sequence, and then running an optimizer
|
||||||
over them to try and reduce the length of the list - for example, it knows
|
over them to try and reduce the length of the list - for example, it knows
|
||||||
that ``CreateModel`` and ``DeleteModel`` cancel each other out, and it knows
|
that :class:`~django.db.migrations.operations.CreateModel` and
|
||||||
that ``AddColumn`` can be rolled into ``CreateModel``.
|
:class:`~django.db.migrations.operations.DeleteModel` cancel each other out,
|
||||||
|
and it knows that :class:`~django.db.migrations.operations.AddField` can be
|
||||||
|
rolled into :class:`~django.db.migrations.operations.CreateModel`.
|
||||||
|
|
||||||
Once the operation sequence has been reduced as much as possible - the amount
|
Once the operation sequence has been reduced as much as possible - the amount
|
||||||
possible depends on how closely intertwined your models are and if you have
|
possible depends on how closely intertwined your models are and if you have
|
||||||
any RunSQL or RunPython operations (which can't be optimized through) - Django
|
any :class:`~django.db.migrations.operations.RunSQL`
|
||||||
will them write it back out into a new set of initial migration files.
|
or :class:`~django.db.migrations.operations.RunPython` operations (which can't
|
||||||
|
be optimized through) - Django will them write it back out into a new set of
|
||||||
|
initial migration files.
|
||||||
|
|
||||||
These files are marked to say they replace the previously-squashed migrations,
|
These files are marked to say they replace the previously-squashed migrations,
|
||||||
so they can coexist with the old migration files, and Django will intelligently
|
so they can coexist with the old migration files, and Django will intelligently
|
||||||
|
@ -452,9 +457,9 @@ work::
|
||||||
Note that model interdependencies in Django can get very complex, and squashing
|
Note that model interdependencies in Django can get very complex, and squashing
|
||||||
may occasionally result in an optimized migration that doesn't work or is
|
may occasionally result in an optimized migration that doesn't work or is
|
||||||
impossible to run. When this occurs, you can re-try with ``--no-optimize``, but
|
impossible to run. When this occurs, you can re-try with ``--no-optimize``, but
|
||||||
please file a bug report either way detailing the models and their
|
please `file a bug report <https://code.djangoproject.com/newticket>`_ either
|
||||||
relationships so we can improve the optimizer to handle your case.
|
way detailing the models and their relationships so we can improve the
|
||||||
|
optimizer to handle your case.
|
||||||
|
|
||||||
.. _migration-serializing:
|
.. _migration-serializing:
|
||||||
|
|
||||||
|
@ -508,7 +513,6 @@ available at the top level of a module it is not serializable.
|
||||||
Django will write out the value as an instantiation of your class with the
|
Django will write out the value as an instantiation of your class with the
|
||||||
given arguments, similar to the way it writes out references to Django fields.
|
given arguments, similar to the way it writes out references to Django fields.
|
||||||
|
|
||||||
|
|
||||||
Upgrading from South
|
Upgrading from South
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
|
@ -517,9 +521,13 @@ If you already have pre-existing migrations created with
|
||||||
``django.db.migrations`` is quite simple:
|
``django.db.migrations`` is quite simple:
|
||||||
|
|
||||||
* Ensure all installs are fully up-to-date with their migrations
|
* Ensure all installs are fully up-to-date with their migrations
|
||||||
* Delete all your (numbered) migration files, but not the directory or __init__.py - make sure you remove the ``.pyc`` files too.
|
* Delete all your (numbered) migration files, but not the directory or
|
||||||
* Run ``python manage.py makemigrations``. Django should see the empty migration directories and make new initial migrations in the new format.
|
``__init__.py`` - make sure you remove the ``.pyc`` files too.
|
||||||
* Run ``python manage.py migrate``. Django will see that the tables for the initial migrations already exist and mark them as applied without running them.
|
* Run ``python manage.py makemigrations``. Django should see the empty
|
||||||
|
migration directories and make new initial migrations in the new format.
|
||||||
|
* Run ``python manage.py migrate``. Django will see that the tables for the
|
||||||
|
initial migrations already exist and mark them as applied without running
|
||||||
|
them.
|
||||||
|
|
||||||
That's it! The only complication is if you have a circular dependency loop
|
That's it! The only complication is if you have a circular dependency loop
|
||||||
of foreign keys; in this case, ``makemigrations`` might make more than one
|
of foreign keys; in this case, ``makemigrations`` might make more than one
|
||||||
|
|
Loading…
Reference in New Issue