mirror of
https://github.com/django/django.git
synced 2024-12-24 01:55:49 +00:00
Improved formatting and links of migration docs.
This commit is contained in:
parent
8905fcbda6
commit
ab8d8e00c9
@ -2,39 +2,39 @@
|
||||
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.
|
||||
|
||||
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
|
||||
your models since the last migration so it can automatically write
|
||||
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
|
||||
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
|
||||
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.
|
||||
|
||||
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``,
|
||||
but be aware that manually adding schema-altering operations can confuse the
|
||||
migration autodetector and make resulting runs of ``makemigrations`` output
|
||||
incorrect code.
|
||||
migration autodetector and make resulting runs of :djadmin:`makemigrations`
|
||||
output incorrect code.
|
||||
|
||||
All of the core Django operations are available from the
|
||||
``django.db.migrations.operations`` module.
|
||||
|
||||
|
||||
Schema Operations
|
||||
=================
|
||||
|
||||
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
|
||||
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
|
||||
inheriting from the standard ``models.Model``.
|
||||
|
||||
|
||||
DeleteModel
|
||||
-----------
|
||||
::
|
||||
|
||||
DeleteModel(name)
|
||||
.. class:: DeleteModel(name)
|
||||
|
||||
Deletes the model from the project history and its table from the database.
|
||||
|
||||
|
||||
RenameModel
|
||||
-----------
|
||||
::
|
||||
|
||||
RenameModel(old_name, new_name)
|
||||
.. class:: RenameModel(old_name, new_name)
|
||||
|
||||
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
|
||||
lose any data in the old table.
|
||||
|
||||
|
||||
AlterModelTable
|
||||
---------------
|
||||
::
|
||||
|
||||
AlterModelTable(name, table)
|
||||
|
||||
Changes the model's table name (the ``db_table`` option on the ``Meta`` subclass)
|
||||
.. class:: AlterModelTable(name, table)
|
||||
|
||||
Changes the model's table name (the :attr:`~django.db.models.Options.db_table`
|
||||
option on the ``Meta`` subclass).
|
||||
|
||||
AlterUniqueTogether
|
||||
-------------------
|
||||
::
|
||||
|
||||
AlterUniqueTogether(name, unique_together)
|
||||
|
||||
Changes the model's set of unique constraints
|
||||
(the ``unique_together`` option on the ``Meta`` subclass)
|
||||
.. class:: AlterUniqueTogether(name, unique_together)
|
||||
|
||||
Changes the model's set of unique constraints (the
|
||||
:attr:`~django.db.models.Options.unique_together` option on the ``Meta``
|
||||
subclass).
|
||||
|
||||
AlterIndexTogether
|
||||
------------------
|
||||
::
|
||||
|
||||
AlterIndexTogether(name, index_together)
|
||||
|
||||
Changes the model's set of custom indexes
|
||||
(the ``index_together`` option on the ``Meta`` subclass)
|
||||
.. class:: AlterIndexTogether(name, index_together)
|
||||
|
||||
Changes the model's set of custom indexes (the
|
||||
:attr:`~django.db.models.Options.index_together` option on the ``Meta``
|
||||
subclass).
|
||||
|
||||
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
|
||||
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
|
||||
defaults, and always applies them in the Django ORM code.
|
||||
|
||||
|
||||
RemoveField
|
||||
-----------
|
||||
::
|
||||
|
||||
RemoveField(model_name, name)
|
||||
.. class:: RemoveField(model_name, name)
|
||||
|
||||
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
|
||||
from any data loss, which of course is irreversible).
|
||||
|
||||
|
||||
AlterField
|
||||
----------
|
||||
::
|
||||
|
||||
AlterField(model_name, name, field)
|
||||
.. class:: AlterField(model_name, name, field)
|
||||
|
||||
Alters a field's definition, including changes to its type, ``null``, ``unique``,
|
||||
``db_column`` and other field attributes.
|
||||
Alters a field's definition, including changes to its type,
|
||||
: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
|
||||
cannot change a text-type field like ``models.TextField()`` into a number-type
|
||||
field like ``models.IntegerField()`` on most databases.
|
||||
|
||||
|
||||
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
|
||||
==================
|
||||
|
||||
.. _operation-run-sql:
|
||||
|
||||
RunSQL
|
||||
------
|
||||
|
||||
::
|
||||
|
||||
RunSQL(sql, reverse_sql=None, state_operations=None)
|
||||
.. class:: RunSQL(sql, reverse_sql=None, state_operations=None)
|
||||
|
||||
Allows running of arbitrary SQL on the database - useful for more advanced
|
||||
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
|
||||
|
||||
.. _operation-run-python:
|
||||
|
||||
RunPython
|
||||
---------
|
||||
|
||||
::
|
||||
|
||||
RunPython(code, reverse_code=None)
|
||||
.. class:: RunPython(code, reverse_code=None)
|
||||
|
||||
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
|
||||
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
|
||||
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``
|
||||
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
|
||||
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
|
||||
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)
|
||||
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
|
||||
the autodetector will stop working correctly.
|
||||
|
||||
|
||||
SeparateDatabaseAndState
|
||||
------------------------
|
||||
|
||||
::
|
||||
|
||||
SeparateDatabaseAndState(database_operations=None, state_operations=None)
|
||||
.. class:: SeparateDatabaseAndState(database_operations=None, state_operations=None)
|
||||
|
||||
A highly specialized operation that let you mix and match the database
|
||||
(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
|
||||
list. Do not use this operation unless you're very sure you know what you're doing.
|
||||
|
||||
|
||||
Writing your own
|
||||
================
|
||||
|
||||
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
|
||||
of an Operation looks like this::
|
||||
of an ``Operation`` looks like this::
|
||||
|
||||
from django.db.migrations.operations.base import Operation
|
||||
|
||||
@ -317,7 +292,7 @@ historical models.
|
||||
|
||||
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
|
||||
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
|
||||
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.
|
||||
|
||||
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
|
||||
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
|
||||
migrations will look for: ``can_rollback_ddl`` and
|
||||
``supports_combined_alters`` are the most important.
|
||||
@ -41,9 +45,7 @@ Methods
|
||||
execute
|
||||
-------
|
||||
|
||||
::
|
||||
|
||||
execute(sql, params=[])
|
||||
.. method:: BaseDatabaseSchemaEditor.execute(sql, params=[])
|
||||
|
||||
Executes the SQL statement passed in, with parameters if supplied. This
|
||||
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(model)
|
||||
.. method:: BaseDatabaseSchemaEditor.create_model(model)
|
||||
|
||||
Creates a new table in the database for the provided model, along with any
|
||||
unique constraints or indexes it requires.
|
||||
|
||||
|
||||
delete_model
|
||||
------------
|
||||
|
||||
::
|
||||
|
||||
delete_model(model)
|
||||
.. method:: BaseDatabaseSchemaEditor.delete_model(model)
|
||||
|
||||
Drops the model's table in the database along with any unique constraints
|
||||
or indexes it has.
|
||||
|
||||
|
||||
alter_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.
|
||||
.. method:: BaseDatabaseSchemaEditor.alter_unique_together(model, old_unique_together, new_unique_together)
|
||||
|
||||
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(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.
|
||||
.. method:: BaseDatabaseSchemaEditor.alter_index_together(model, old_index_together, new_index_together)
|
||||
|
||||
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(model, old_db_table, new_db_table)
|
||||
.. method:: BaseDatabaseSchemaEditor.alter_db_table(model, old_db_table, new_db_table)
|
||||
|
||||
Renames the model's table from ``old_db_table`` to ``new_db_table``.
|
||||
|
||||
|
||||
alter_db_tablespace
|
||||
-------------------
|
||||
|
||||
::
|
||||
|
||||
alter_db_tablespace(model, old_db_tablespace, new_db_tablespace)
|
||||
.. method:: BaseDatabaseSchemaEditor.alter_db_tablespace(model, old_db_tablespace, new_db_tablespace)
|
||||
|
||||
Moves the model's table from one tablespace to another.
|
||||
|
||||
|
||||
add_field
|
||||
---------
|
||||
|
||||
::
|
||||
|
||||
add_field(model, field)
|
||||
.. method:: BaseDatabaseSchemaEditor.add_field(model, field)
|
||||
|
||||
Adds a column (or sometimes multiple) to the model's table to represent the
|
||||
field. This will also add indexes or a unique constraint
|
||||
if the field has ``db_index=True`` or ``unique=True``.
|
||||
|
||||
If the field is a ManyToManyField without a value for ``through``, instead of
|
||||
creating a column, it will make a table to represent the relationship. If
|
||||
If the field is a ``ManyToManyField`` without a value for ``through``, instead
|
||||
of creating a column, it will make a table to represent the relationship. If
|
||||
``through`` is provided, it is a no-op.
|
||||
|
||||
If the field is a ``ForeignKey``, this will also add the foreign key
|
||||
constraint to the column.
|
||||
|
||||
|
||||
remove_field
|
||||
------------
|
||||
|
||||
::
|
||||
|
||||
remove_field(model, field)
|
||||
.. method:: BaseDatabaseSchemaEditor.remove_field(model, field)
|
||||
|
||||
Removes the column(s) representing the field from the model's table, along
|
||||
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
|
||||
``through`` is provided, it is a no-op.
|
||||
|
||||
|
||||
alter_field
|
||||
------------
|
||||
|
||||
::
|
||||
|
||||
alter_field(model, old_field, new_field, strict=False)
|
||||
.. method:: BaseDatabaseSchemaEditor.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
|
||||
includes changing the name of the column (the ``db_column`` attribute),
|
||||
changing the type of the field (if the field class changes), changing
|
||||
the ``NULL`` status of the field, adding or removing field-only unique
|
||||
constraints and indexes, changing primary key, and changing the destination
|
||||
of ForeignKey constraints.
|
||||
includes changing the name of the column (the
|
||||
:attr:`~django.db.models.Field.db_column` attribute), changing the type of the
|
||||
field (if the field class changes), changing the ``NULL`` status of the field,
|
||||
adding or removing field-only unique constraints and indexes, changing primary
|
||||
key, and changing the destination of ``ForeignKey`` constraints.
|
||||
|
||||
The most common transformation this cannot do is transforming a
|
||||
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``
|
||||
and ``add_field`` should be called separately.
|
||||
``ManyToManyField`` into a normal Field or vice-versa; Django cannot do this
|
||||
without losing data, and so it will refuse to do it. Instead,
|
||||
:meth:`.remove_field` and :meth:`.add_field` should be called separately.
|
||||
|
||||
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
|
||||
|
@ -639,8 +639,9 @@ Management Commands
|
||||
* :ref:`initial-sql` now works better if the sqlparse_ Python library is
|
||||
installed.
|
||||
|
||||
Note that it's deprecated in favor of the :ref:`RunSQL <operation-run-sql>`
|
||||
operation of migrations, which benefits from the improved behavior.
|
||||
Note that it's deprecated in favor of the
|
||||
:class:`~django.db.migrations.operations.RunSQL` operation of migrations,
|
||||
which benefits from the improved behavior.
|
||||
|
||||
.. _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
|
||||
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>`_,
|
||||
provided support for these additional types of change, but it was considered
|
||||
@ -53,7 +53,8 @@ staging machines, and eventually your production machines.
|
||||
|
||||
.. note::
|
||||
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
|
||||
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
|
||||
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 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``.
|
||||
|
||||
This means that when you run the migrations, the ``authors`` migration runs
|
||||
first and creates the table the ``ForeignKey`` references, and then the migration
|
||||
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
|
||||
without the table it's referencing existing and your database would
|
||||
If this didn't happen, the migration would try to create the ``ForeignKey``
|
||||
column without the table it's referencing existing and your database would
|
||||
throw an error.
|
||||
|
||||
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:
|
||||
|
||||
* ``dependencies``, a list of migrations this one depends on.
|
||||
* ``operations``, a list of Operation classes that define what this migration
|
||||
does.
|
||||
* ``operations``, a list of ``Operation`` classes that define what this
|
||||
migration does.
|
||||
|
||||
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
|
||||
@ -252,9 +253,9 @@ Custom fields
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
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
|
||||
migrations try to modify those tables.
|
||||
|
||||
|
||||
.. _historical-models:
|
||||
|
||||
Historical models
|
||||
@ -293,9 +293,9 @@ Historical models
|
||||
|
||||
When you run migrations, Django is working from historical versions of
|
||||
your models stored in the migration files. If you write Python code
|
||||
using the ``django.db.migrations.RunPython`` operation, or if you have
|
||||
``allow_migrate`` methods on your database routers, you will be exposed
|
||||
to these versions of your models.
|
||||
using the :class:`~django.db.migrations.operations.RunPython` operation, or if
|
||||
you have ``allow_migrate`` methods on your database routers, you will be
|
||||
exposed to these versions of your models.
|
||||
|
||||
Because it's impossible to serialize arbitrary Python code, these historical
|
||||
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::
|
||||
|
||||
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
|
||||
or instance methods. Plan appropriately!
|
||||
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 or instance methods. Plan appropriately!
|
||||
|
||||
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
|
||||
@ -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
|
||||
to these you can opt to move them into a superclass.
|
||||
|
||||
|
||||
.. _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
|
||||
Django are made up of :doc:`Operations </ref/migration-operations>`, and
|
||||
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
|
||||
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 = [
|
||||
]
|
||||
|
||||
Now, all you need to do is create a new function and have RunPython use it.
|
||||
RunPython expects a callable as its argument which takes two arguments - the
|
||||
first is an :doc:`app registry </ref/applications/>` that has the historical
|
||||
versions of all your models loaded into it to match where in your history the
|
||||
migration sits, and the 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!)
|
||||
Now, all you need to do is create a new function and have
|
||||
:class:`~django.db.migrations.operations.RunPython` use it.
|
||||
:class:`~django.db.migrations.operations.RunPython` expects a callable as its argument
|
||||
which takes two arguments - the first is an :doc:`app registry
|
||||
</ref/applications/>` that has the historical versions of all your models
|
||||
loaded into it to match where in your history the migration sits, and the
|
||||
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
|
||||
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.
|
||||
|
||||
If you're interested in the more advanced migration operations, or want
|
||||
to be able to write your own, see our
|
||||
:doc:`migration operations reference </ref/migration-operations>`.
|
||||
to be able to write your own, see the :doc:`migration operations reference
|
||||
</ref/migration-operations>`.
|
||||
|
||||
.. _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.
|
||||
|
||||
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
|
||||
that ``CreateModel`` and ``DeleteModel`` cancel each other out, and it knows
|
||||
that ``AddColumn`` can be rolled into ``CreateModel``.
|
||||
that :class:`~django.db.migrations.operations.CreateModel` and
|
||||
: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
|
||||
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
|
||||
will them write it back out into a new set of initial migration files.
|
||||
any :class:`~django.db.migrations.operations.RunSQL`
|
||||
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,
|
||||
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
|
||||
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
|
||||
please file a bug report either way detailing the models and their
|
||||
relationships so we can improve the optimizer to handle your case.
|
||||
|
||||
please `file a bug report <https://code.djangoproject.com/newticket>`_ either
|
||||
way detailing the models and their relationships so we can improve the
|
||||
optimizer to handle your case.
|
||||
|
||||
.. _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
|
||||
given arguments, similar to the way it writes out references to Django fields.
|
||||
|
||||
|
||||
Upgrading from South
|
||||
--------------------
|
||||
|
||||
@ -517,9 +521,13 @@ If you already have pre-existing migrations created with
|
||||
``django.db.migrations`` is quite simple:
|
||||
|
||||
* 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.
|
||||
* 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.
|
||||
* Delete all your (numbered) migration files, but not the directory or
|
||||
``__init__.py`` - make sure you remove the ``.pyc`` files too.
|
||||
* 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
|
||||
of foreign keys; in this case, ``makemigrations`` might make more than one
|
||||
|
Loading…
Reference in New Issue
Block a user