You are on page 1of 5

================

``SchemaEditor``
================

.. module:: django.db.backends.base.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
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.

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
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
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.

Methods
=======

``execute()``
-------------

.. 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
capture of the SQL to a ``.sql`` file if the user wishes.

``create_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()``
------------------

.. method:: BaseDatabaseSchemaEditor.delete_model(model)

Drops the model's table in the database along with any unique constraints
or indexes it has.

``add_index()``
---------------

.. method:: BaseDatabaseSchemaEditor.add_index(model, index)

.. versionadded:: 1.11

Adds ``index`` to ``model``s table.

``remove_index()``
------------------

.. method:: BaseDatabaseSchemaEditor.remove_index(model, index)

.. versionadded:: 1.11

Removes ``index`` from ``model``s table.

``alter_unique_together()``
---------------------------

.. 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()``
--------------------------

.. 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()``
--------------------

.. 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()``
-------------------------
.. method:: BaseDatabaseSchemaEditor.alter_db_tablespace(model, old_db_tablespace,
new_db_tablespace)

Moves the model's table from one tablespace to another.

``add_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
``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()``
------------------

.. 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
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.

``alter_field()``
-----------------

.. 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
: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,
: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
issue a separate ALTER statement for each change, but will not issue ALTERs
where no change is required (as South often did).

Attributes
==========
All attributes should be considered read-only unless stated otherwise.

``connection``
--------------

.. 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>`.

Microsoft Windows [Versin 10.0.15063]


(c) 2017 Microsoft Corporation. Todos los derechos reservados.

C:\Users\stive>cd proyectosdj

C:\Users\stive\proyectosdj>cd miprimerproyecto

C:\Users\stive\proyectosdj\miprimerproyecto>python manage.py shell


Python 3.6.2rc1 (heads/3.6:268e1fb, Jun 17 2017, 19:01:44) [MSC v.1900 64 bit
(AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from preguntasyrespuestas.models import Preguntas.Respuestas
File "<console>", line 1
from preguntasyrespuestas.models import Preguntas.Respuestas
^
SyntaxError: invalid syntax
>>> from preguntasyrespuestas.models import Preguntas,Respuesta
Traceback (most recent call last):
File "<console>", line 1, in <module>
ImportError: cannot import name 'Preguntas'
>>> from preguntasyrespuestas.models import Pregunta,Respuesta
>>> Pregunta.objects.all()
<QuerySet [<Pregunta: Quien es tu escritor favorito>]>
>>> p = Pregunta.object.get(pk=1)
Traceback (most recent call last):
File "<console>", line 1, in <module>
AttributeError: type object 'Pregunta' has no attribute 'object'
>>> p = Pregunta.objects.get(pk=1)
>>> p.publicado_hoy()
Traceback (most recent call last):
File "<console>", line 1, in <module>
File
"C:\Users\stive\proyectosdj\miprimerproyecto\preguntasyrespuestas\models.py", line
13, in publicado_hoy
return self.fecha_publicacion.date() == timezone.now().date()
NameError: name 'timezone' is not defined
>>> p.publicado_hoy()
Traceback (most recent call last):
File "<console>", line 1, in <module>
File
"C:\Users\stive\proyectosdj\miprimerproyecto\preguntasyrespuestas\models.py", line
13, in publicado_hoy
def publicado_hoy(self):
NameError: name 'timezone' is not defined
>>> from preguntasyrespuestas.models import Pregunta,Respuesta

Microsoft Windows [Versin 10.0.15063]


(c) 2017 Microsoft Corporation. Todos los derechos reservados.

C:\Users\stive>cd proyectosdj

C:\Users\stive\proyectosdj>cd miprimerproyecto

C:\Users\stive\proyectosdj\miprimerproyecto>python manage.py shell


Python 3.6.2rc1 (heads/3.6:268e1fb, Jun 17 2017, 19:01:44) [MSC v.1900 64 bit
(AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from preguntasyrespuestas.models import Pregunta,Respuesta
>>> p = Pregunta.objects.get(pk=1)
>>> p.publicado_hoy()
True
>>> p.respuesta_sel.all()
Traceback (most recent call last):
File "<console>", line 1, in <module>
AttributeError: 'Pregunta' object has no attribute 'respuesta_sel'
>>> p.respuesta_set.all()
<QuerySet []>
>>> p.respuesta_set.create(contenido="Mi preferido es Borges")
<Respuesta: Mi preferido es Borges>
>>> p.respuesta_set.create(contenido="Mi preferido es Antonio Ma")
<Respuesta: Mi preferido es Antonio Ma>
>>> p.respuesta_set.create(contenido="Mi preferido es Pablo Neruda")
<Respuesta: Mi preferido es Pablo Neruda>
>>> Respuesta.objects.filter(contenido="Mi preferido es Borges")
<QuerySet [<Respuesta: Mi preferido es Borges>]>
>>> Respuesta.objects.filter(contenido__contains="Ma")
<QuerySet [<Respuesta: Mi preferido es Antonio Ma>]>
>>> Respuesta.objects.filter(Pregunta__asunto__contains="escritor")
<QuerySet [<Respuesta: Mi preferido es Borges>, <Respuesta: Mi preferido es Antonio
Ma>, <Respuesta: Mi preferido es Pablo Neruda>]>
>>> conjuntoresultados = Respuesta.objects.filter(contenido__contains="Ma")
>>> conjuntoresultados.count()
1
>>> conjuntoresultados.delete()
(1, {'preguntasyrespuestas.Respuesta': 1})
>>> Respuesta.objects.filter(contenido__contains="Ma")
<QuerySet []>
>>>

<!--{{..}}: Es una variable, imprime el valor de una variable


{%...%}: Es un template tag, un tag de plantilla -->

You might also like