2014-04-28 03:05:25 +08:00
|
|
|
|
================
|
|
|
|
|
``SchemaEditor``
|
|
|
|
|
================
|
|
|
|
|
|
2015-01-13 04:20:40 +08:00
|
|
|
|
.. module:: django.db.backends.base.schema
|
2014-04-28 03:05:25 +08:00
|
|
|
|
|
|
|
|
|
.. class:: BaseDatabaseSchemaEditor
|
2014-02-13 02:53:35 +08:00
|
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
|
2014-04-15 01:07:02 +08:00
|
|
|
|
If you are writing or maintaining a third-party database backend for Django,
|
2014-04-28 03:05:25 +08:00
|
|
|
|
you will need to provide a ``SchemaEditor`` implementation in order to work with
|
2020-10-20 15:49:05 +08:00
|
|
|
|
Django'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 tweak the
|
|
|
|
|
syntax a little.
|
2014-04-15 01:07:02 +08:00
|
|
|
|
|
2014-02-13 02:53:35 +08:00
|
|
|
|
Methods
|
|
|
|
|
=======
|
|
|
|
|
|
2016-01-25 05:26:11 +08:00
|
|
|
|
``execute()``
|
|
|
|
|
-------------
|
2014-02-13 02:53:35 +08:00
|
|
|
|
|
2021-08-27 12:12:53 +08:00
|
|
|
|
.. method:: BaseDatabaseSchemaEditor.execute(sql, params=())
|
2014-02-13 02:53:35 +08:00
|
|
|
|
|
|
|
|
|
Executes the SQL statement passed in, with parameters if supplied. This
|
2019-06-17 22:54:55 +08:00
|
|
|
|
is a wrapper around the normal database cursors that allows capture of the SQL
|
|
|
|
|
to a ``.sql`` file if the user wishes.
|
2014-02-13 02:53:35 +08:00
|
|
|
|
|
2016-01-25 05:26:11 +08:00
|
|
|
|
``create_model()``
|
|
|
|
|
------------------
|
2014-02-13 02:53:35 +08:00
|
|
|
|
|
2014-04-28 03:05:25 +08:00
|
|
|
|
.. method:: BaseDatabaseSchemaEditor.create_model(model)
|
2014-02-13 02:53:35 +08:00
|
|
|
|
|
2014-04-15 01:07:02 +08:00
|
|
|
|
Creates a new table in the database for the provided model, along with any
|
|
|
|
|
unique constraints or indexes it requires.
|
|
|
|
|
|
2016-01-25 05:26:11 +08:00
|
|
|
|
``delete_model()``
|
|
|
|
|
------------------
|
2014-02-13 02:53:35 +08:00
|
|
|
|
|
2014-04-28 03:05:25 +08:00
|
|
|
|
.. method:: BaseDatabaseSchemaEditor.delete_model(model)
|
2014-02-13 02:53:35 +08:00
|
|
|
|
|
2014-04-15 01:07:02 +08:00
|
|
|
|
Drops the model's table in the database along with any unique constraints
|
|
|
|
|
or indexes it has.
|
|
|
|
|
|
2016-07-07 01:08:34 +08:00
|
|
|
|
``add_index()``
|
|
|
|
|
---------------
|
|
|
|
|
|
|
|
|
|
.. method:: BaseDatabaseSchemaEditor.add_index(model, index)
|
|
|
|
|
|
|
|
|
|
Adds ``index`` to ``model``’s table.
|
|
|
|
|
|
|
|
|
|
``remove_index()``
|
|
|
|
|
------------------
|
|
|
|
|
|
|
|
|
|
.. method:: BaseDatabaseSchemaEditor.remove_index(model, index)
|
|
|
|
|
|
|
|
|
|
Removes ``index`` from ``model``’s table.
|
|
|
|
|
|
2019-08-11 09:26:44 +08:00
|
|
|
|
``add_constraint()``
|
|
|
|
|
--------------------
|
|
|
|
|
|
|
|
|
|
.. method:: BaseDatabaseSchemaEditor.add_constraint(model, constraint)
|
|
|
|
|
|
|
|
|
|
Adds ``constraint`` to ``model``'s table.
|
|
|
|
|
|
|
|
|
|
``remove_constraint()``
|
|
|
|
|
-----------------------
|
|
|
|
|
|
|
|
|
|
.. method:: BaseDatabaseSchemaEditor.remove_constraint(model, constraint)
|
|
|
|
|
|
|
|
|
|
Removes ``constraint`` from ``model``'s table.
|
|
|
|
|
|
2016-01-25 05:26:11 +08:00
|
|
|
|
``alter_unique_together()``
|
|
|
|
|
---------------------------
|
2014-02-13 02:53:35 +08:00
|
|
|
|
|
2014-04-28 03:05:25 +08:00
|
|
|
|
.. method:: BaseDatabaseSchemaEditor.alter_unique_together(model, old_unique_together, new_unique_together)
|
2014-04-15 01:07:02 +08:00
|
|
|
|
|
2014-04-28 03:05:25 +08:00
|
|
|
|
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.
|
2014-02-13 02:53:35 +08:00
|
|
|
|
|
2016-01-25 05:26:11 +08:00
|
|
|
|
``alter_index_together()``
|
|
|
|
|
--------------------------
|
2014-02-13 02:53:35 +08:00
|
|
|
|
|
2014-04-28 03:05:25 +08:00
|
|
|
|
.. method:: BaseDatabaseSchemaEditor.alter_index_together(model, old_index_together, new_index_together)
|
2014-04-15 01:07:02 +08:00
|
|
|
|
|
2014-04-28 03:05:25 +08:00
|
|
|
|
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.
|
2014-02-13 02:53:35 +08:00
|
|
|
|
|
2016-01-25 05:26:11 +08:00
|
|
|
|
``alter_db_table()``
|
|
|
|
|
--------------------
|
2014-02-13 02:53:35 +08:00
|
|
|
|
|
2014-04-28 03:05:25 +08:00
|
|
|
|
.. method:: BaseDatabaseSchemaEditor.alter_db_table(model, old_db_table, new_db_table)
|
2014-02-13 02:53:35 +08:00
|
|
|
|
|
2014-04-15 01:07:02 +08:00
|
|
|
|
Renames the model's table from ``old_db_table`` to ``new_db_table``.
|
|
|
|
|
|
2016-01-25 05:26:11 +08:00
|
|
|
|
``alter_db_tablespace()``
|
|
|
|
|
-------------------------
|
2014-02-13 02:53:35 +08:00
|
|
|
|
|
2014-04-28 03:05:25 +08:00
|
|
|
|
.. method:: BaseDatabaseSchemaEditor.alter_db_tablespace(model, old_db_tablespace, new_db_tablespace)
|
2014-02-13 02:53:35 +08:00
|
|
|
|
|
2014-04-15 01:07:02 +08:00
|
|
|
|
Moves the model's table from one tablespace to another.
|
|
|
|
|
|
2016-01-25 05:26:11 +08:00
|
|
|
|
``add_field()``
|
|
|
|
|
---------------
|
2014-02-13 02:53:35 +08:00
|
|
|
|
|
2014-04-28 03:05:25 +08:00
|
|
|
|
.. method:: BaseDatabaseSchemaEditor.add_field(model, field)
|
2014-02-13 02:53:35 +08:00
|
|
|
|
|
2014-04-15 01:07:02 +08:00
|
|
|
|
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``.
|
|
|
|
|
|
2014-04-28 03:05:25 +08:00
|
|
|
|
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
|
2014-04-15 01:07:02 +08:00
|
|
|
|
``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.
|
|
|
|
|
|
2016-01-25 05:26:11 +08:00
|
|
|
|
``remove_field()``
|
|
|
|
|
------------------
|
2014-02-13 02:53:35 +08:00
|
|
|
|
|
2014-04-28 03:05:25 +08:00
|
|
|
|
.. method:: BaseDatabaseSchemaEditor.remove_field(model, field)
|
2014-02-13 02:53:35 +08:00
|
|
|
|
|
2014-04-15 01:07:02 +08:00
|
|
|
|
Removes the column(s) representing the field from the model's table, along
|
|
|
|
|
with any unique constraints, foreign key constraints, or indexes caused by
|
|
|
|
|
that field.
|
|
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
|
2016-01-25 05:26:11 +08:00
|
|
|
|
``alter_field()``
|
|
|
|
|
-----------------
|
2014-02-13 02:53:35 +08:00
|
|
|
|
|
2014-04-28 03:05:25 +08:00
|
|
|
|
.. method:: BaseDatabaseSchemaEditor.alter_field(model, old_field, new_field, strict=False)
|
2014-04-15 01:07:02 +08:00
|
|
|
|
|
|
|
|
|
This transforms the field on the model from the old field to the new one. This
|
2014-04-28 03:05:25 +08:00
|
|
|
|
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.
|
2014-04-15 01:07:02 +08:00
|
|
|
|
|
|
|
|
|
The most common transformation this cannot do is transforming a
|
2014-04-28 03:05:25 +08:00
|
|
|
|
``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.
|
2014-04-15 01:07:02 +08:00
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
issue a separate ALTER statement for each change, but will not issue ALTERs
|
2020-03-23 18:55:58 +08:00
|
|
|
|
where no change is required.
|
2015-01-01 11:16:51 +08:00
|
|
|
|
|
|
|
|
|
Attributes
|
|
|
|
|
==========
|
|
|
|
|
|
|
|
|
|
All attributes should be considered read-only unless stated otherwise.
|
|
|
|
|
|
2016-01-25 05:26:11 +08:00
|
|
|
|
``connection``
|
|
|
|
|
--------------
|
2015-01-01 11:16:51 +08:00
|
|
|
|
|
|
|
|
|
.. attribute:: SchemaEditor.connection
|
|
|
|
|
|
|
|
|
|
A connection object to the database. A useful attribute of the connection is
|
|
|
|
|
``alias`` which can be used to determine the name of the database being
|
|
|
|
|
accessed.
|
|
|
|
|
|
|
|
|
|
This is useful when doing data migrations for :ref:`migrations with multiple
|
|
|
|
|
databases <data-migrations-and-multiple-databases>`.
|