Kaydet (Commit) dbe82e74 authored tarafından Andrew Godwin's avatar Andrew Godwin

Add reference documentation for operations and stubs for schemaeditor.

üst bad9456b
...@@ -73,7 +73,9 @@ manipulating the data of your Web application. Learn more about it below: ...@@ -73,7 +73,9 @@ manipulating the data of your Web application. Learn more about it below:
:doc:`Accessing related objects <ref/models/relations>` :doc:`Accessing related objects <ref/models/relations>`
* **Migrations:** * **Migrations:**
:doc:`Introduction to Migrations<topics/migrations>` :doc:`Introduction to Migrations<topics/migrations>` |
:doc:`Operations reference <ref/migration-operations>` |
:doc:`SchemaEditor <ref/schema-editor>`
* **Advanced:** * **Advanced:**
:doc:`Managers <topics/db/managers>` | :doc:`Managers <topics/db/managers>` |
......
This diff is collapsed.
============
SchemaEditor
============
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
database abstraction layer that turns things like "create a model" or
"delete a field" into SQL - which is the job of the ``SchemaEditor``.
It's unlikely that you will want to interact directly with ``SchemaEditor`` as
a normal developer using Django, but if you want to write your own migration
system, or have more advanced needs, it's a lot nicer than writing SQL.
Each database backend in Django supplies its own version of ``SchemaEditor``,
and it's always accessible via the ``connection.schema_editor()`` context
manager::
with connection.schema_editor() as schema_editor:
schema_editor.delete_model(MyModel)
It must be used via the context manager as this allows it to manage things
like transactions and deferred SQL (like creating ``ForeignKey`` constraints).
It exposes all possible operations as methods, that should be called in
the order you wish changes to be applied. Some possible operations or types
of change are not possible on all databases - for example, MyISAM does not
support foreign key constraints.
Methods
=======
execute
-------
::
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
capture of the SQL to a ``.sql`` file if the user wishes.
create_model
------------
::
create_model(model)
delete_model
------------
::
delete_model(model)
alter_unique_together
---------------------
::
alter_unique_together(model, old_unique_together, new_unique_together)
alter_index_together
--------------------
::
alter_index_together(model, old_index_together, new_index_together)
alter_db_table
--------------
::
alter_db_table(model, old_db_table, new_db_table)
alter_db_tablespace
-------------------
::
alter_db_tablespace(model, old_db_tablespace, new_db_tablespace)
add_field
---------
::
add_field(model, field)
remove_field
------------
::
remove_field(model, field)
alter_field
------------
::
alter_field(model, old_field, new_field, strict=False)
...@@ -60,7 +60,7 @@ Backend Support ...@@ -60,7 +60,7 @@ Backend Support
Migrations are supported on all backends that Django ships with, as well Migrations are supported on all backends that Django ships with, as well
as any third-party backends if they have programmed in support for schema as any third-party backends if they have programmed in support for schema
alteration (done via the ``SchemaEditor`` class). alteration (done via the :doc:`SchemaEditor </ref/schema-editor>` class).
However, some databases are more capable than others when it comes to However, some databases are more capable than others when it comes to
schema migrations; some of the caveats are covered below. schema migrations; some of the caveats are covered below.
...@@ -311,6 +311,84 @@ from these base classes inherit normally, so if you absolutely need access ...@@ -311,6 +311,84 @@ 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
---------------
As well as changing the database schema, you can also use migrations to change
the data in the database itself, in conjunction with the schema if you want.
Migrations that alter data are usually called "data migrations"; they're best
written as separate migrations, sitting alongside your schema migrations.
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>`.
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)::
python manage.py makemigrations --empty yourappname
Then, open up the file; it should look something like this::
# encoding: utf8
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('yourappname', '0001_initial'),
]
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!)
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
and realised that not everyone has first and last names). All we
need to do is use the historical model and iterate over the rows::
# encoding: utf8
from django.db import models, migrations
def combine_names(apps, schema_editor):
# We can't import the Person model directly as it may be a newer
# version than this migration expects. We use the historical version.
Person = apps.get_model("yourappname", "Person")
for person in Person.objects.all():
person.name = "%s %s" % (person.first_name, person.last_name)
person.save()
class Migration(migrations.Migration):
dependencies = [
('yourappname', '0001_initial'),
]
operations = [
migrations.RunPython(combine_names),
]
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>`.
.. _migration-serializing: .. _migration-serializing:
Serializing values Serializing values
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment