Categorías
Python

La implementación de una interfaz en Python

 

Tabla de Contenidos

  • Cómo Django sabe qué migraciones a Aplicar
  • La migración FileMigration OperationsMigration DependenciesViewing la migración
  • Migración Operaciones
  • Migración Dependencias
  • Visualización de los cambios de la migración
  • Cómo Django Detecta a su ModelsPlaying Ajedrez Con DjangoUnderstanding SeparateDatabaseAndState
  • jugando al ajedrez con Django
  • Comprender SeparateDatabaseAndState
  • Conclusión
  • Migración Operaciones
  • Migración dependencias
  • Visualización de la migración
  • jugando al ajedrez con Django
  • Comprender SeparateDatabaseAndState

Este es el segundo artículo de nuestra Django migraciones serie:

  • Parte 1: Django Migraciones: A Primer
  • Parte 2: profundizando en Django migraciones (artículo actual)
  • Parte 3: migración de datos s
  • vídeo: Django 1.7 Migraciones – Una cartilla

En el artículo anterior de esta serie, que aprendió acerca de los efectos de las migraciones de Django. Que se haya familiarizado con los patrones de uso fundamentales como la creación y aplicación de las migraciones. Ahora es el momento de profundizar en el sistema de migración y echar un vistazo a algunos de sus mecanismos subyacentes.

Al final de este artículo, usted sabrá:

  • Cómo Django realiza un seguimiento de las migraciones
  • ¿Cómo saben las migraciones, que las operaciones de base de datos para realizar
  • ¿Cómo se definen las dependencias entre las migraciones

Una vez que haya envuelto alrededor de su cabeza esta parte del sistema de migración de Django, usted estará bien preparado para crear sus propias migraciones personalizados. derecho salto Vamos en donde lo dejamos!

En este artículo se utiliza el proyecto Django Django bitcoin_tracker construida en Migraciones: Una cartilla. Usted puede volver a crear ese proyecto, trabajando a través de ese artículo o se puede descargar el código fuente:

Descargar Código Fuente: Haga clic aquí para descargar el código para las migraciones de Django proyecta que va a utilizar en este artículo.

Cómo Django sabe qué migraciones a Aplicar recapitulación de

Let el último paso del artículo anterior en la serie. Que ha creado una migración y después se aplican todas las migraciones disponibles con python manage.py migrate.If ese comando se ejecutó correctamente, entonces sus tablas de la base coinciden ahora con las definiciones de su modelo.

¿Qué ocurre si se ejecuta ese comando de nuevo? Vamos a tratar de usted mismo:

$ python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, historical_data, sessions
Running migrations:
No migrations to apply.

No pasó nada! Una vez que la migración se ha aplicado a una base de datos, Django no se aplicará esta migración a esa base de datos en particular de nuevo. Asegurar que la migración se aplica una sola vez requiere hacer el seguimiento de las migraciones que se han aplicado.

Django usa una tabla de base de datos llamada django_migrations. Django crea automáticamente esta tabla en su base de datos la primera vez que se aplica ningún migraciones. Para cada migración que se aplica o simulada, una nueva fila se inserta en la tabla.

Por ejemplo, esto es lo que esta tabla se ve como en nuestro proyecto bitcoin_tracker:

Como se puede ver, hay una entrada para cada migración aplicada. La mesa no sólo contiene las migraciones de nuestra aplicación historical_data, sino también las migraciones de todas las demás aplicaciones instaladas.

La próxima vez que se ejecutan las migraciones, Django se saltará las migraciones que figuran en la tabla de base de datos. Esto significa que, aunque se cambie manualmente el archivo de una migración que ya ha sido aplicado, Django ignorar estos cambios, siempre y cuando ya hay una entrada para él en la base de datos.

Se puede engañar a Django en volver a ejecutar una migración mediante la supresión de la fila correspondiente de la tabla, pero esto rara vez es una buena idea y puede dejar con un sistema de migración roto. Archivo

La migración

¿Qué ocurre cuando se ejecuta python manage.py makemigrations ? Django miradas de los cambios realizados en los modelos en su aplicación . Si encuentra alguno, como un modelo que se ha añadido, a continuación, se crea un archivo de migración en el subdirectorio migraciones. Este archivo de migración contiene una lista de operaciones para llevar el esquema de base de datos en sincronía con su definición del modelo.

Nota: Su aplicación tiene que aparecer en el entorno INSTALLED_APPS, y debe contener un directorio con un archivo de migraciones __init__.py. De lo contrario, Django no creará ningún migraciones para ello.

El directorio de las migraciones se crea automáticamente cuando se crea una nueva aplicación con el comando de gestión startapp, pero es fácil olvidar al crear una aplicación manualmente.

Los archivos de migración son sólo Python, así que vamos a echar un vistazo a la primera archivo de migración en la aplicación historical_prices. Puede encontrarlo en historical_prices / migraciones / 0001_initial.py. Debe ser algo como esto:

from django.db import models, migrations

class Migration(migrations.Migration):
dependencies = []
operations = [
migrations.CreateModel(
name='PriceHistory',
fields=[
('id', models.AutoField(
verbose_name='ID',
serialize=False,
primary_key=True,
auto_created=True)),
('date', models.DateTimeField(auto_now_add=True)),
('price', models.DecimalField(decimal_places=2, max_digits=5)),
('volume', models.PositiveIntegerField()),
('total_btc', models.PositiveIntegerField()),
],
options={
},
bases=(models.Model,),
),
]

Como se puede ver, que contiene una sola clase llamada migración que hereda de django.db.migrations.Migration. Esta es la clase que el marco de la migración va a buscar y ejecutar cuando se pregunta a aplicar las migraciones. La clase

Migración contiene dos listas principales: la mirada de

Migración Operaciones

Veamos las operaciones de lista en primer lugar. Esta tabla contiene las operaciones que se van a llevar a cabo como parte de la migración. Las operaciones son subclases de la clase django.db.migrations.operations.base.Operation. Estas son las operaciones más comunes que se construyen en Django:

Nota cómo las operaciones se nombran después de los cambios realizados en las definiciones de modelos, no las acciones que se realizan en la base de datos. Cuando se aplica una migración, cada operación es responsable de generar las sentencias SQL necesarias para su base de datos específica. Por ejemplo, CreateModel generaría una declaración SQL CREATE TABLE.

Fuera de la caja, las migraciones tiene soporte para todas las bases de datos estándar que soporta Django. Así que si usted se pega a las operaciones que se enumeran aquí, entonces usted puede hacer más o menos cualquier cambio en sus modelos que desee, sin tener que preocuparse por el SQL subyacente. Que todo está hecho para ti.

Nota: En algunos casos, Django no puede detectar correctamente los cambios. Si cambia el nombre de modelo y cambiar varias de sus campos, a continuación, Django podría confundir esto con un nuevo modelo.

En lugar de un RenameModel y varias operaciones AlterField, se creará un deleteModel y una operación de CreateModel. En lugar de cambiar el nombre de la tabla de base de datos para el modelo, lo descartará y crear una nueva tabla con el nombre nuevo, eliminando eficazmente todos sus datos!

Que sea un hábito para comprobar las migraciones generadas y probarlos en una copia de la base de datos antes de ejecutarlos en los datos de producción.

Django proporciona tres más clases de operación para los casos de uso avanzada:

Con estas operaciones, se puede hacer básicamente cualquier cambio que desee a su base de datos. Sin embargo, usted no encontrará estas operaciones en una migración que se ha creado de forma automática con el comando de gestión makemigrations.

Desde Django 2.0, también hay un par de operaciones de PostgreSQL-específicos disponibles en django.contrib.postgres.operations que se puede utilizar para instalar varias extensiones PostgreSQL:

  • BtreeGinExtension
  • BtreeGistExtension
  • CITextExtension
  • CryptoExtension
  • HStoreExtension
  • TrigramExtension
  • UnaccentExtension

Tenga en cuenta que una migración que contiene una de estas operaciones requiere que un usuario de base de datos con privilegios de superusuario.

Por último, pero no menos importante, también puede crear sus propias clases de operación. Si desea ver en eso, a continuación, echar un vistazo a la documentación de Django en la creación de las operaciones de migración personalizado.

Migración Dependencias

la lista de dependencias en una clase de migración contiene ningún migraciones que se deben aplicar antes de que esta migración puede ser aplicado.

En la migración 0001_initial.py que viste anteriormente, nada tiene que aplicarse antes así que no hay dependencias. Vamos a echar un vistazo a la segunda migración en la aplicación historical_prices. En el 0002_switch_to_decimals.py archivo, el atributo dependencias de Migración tiene una entrada:

from django.db import migrations, models

class Migration(migrations.Migration):
dependencies = [
('historical_data', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='pricehistory',
name='volume',
field=models.DecimalField(decimal_places=3, max_digits=7),
),
]

La dependencia de arriba dice que 0001_initial migración del historical_data aplicación debe ejecutarse en primer lugar. Esto tiene sentido, ya que el 0001_initial migración crea la tabla que contiene el campo que los 0002_switch_to_decimals migración quiere cambiar.

Una migración también puede tener una dependencia de una migración desde otra aplicación, como esto:

class Migration(migrations.Migration):
...

dependencies = [
('auth', '0009_alter_user_last_name_max_length'),
]

Esto suele ser necesario si un modelo tiene una clave externa que apunta a un modelo en otra aplicación.

Como alternativa, también puede hacer cumplir una migración que se ejecuta antes de otra migración mediante el atributo run_ antes :

class Migration(migrations.Migration):
...

run_before = [
('third_party_app', '0001_initial'),
]

dependencias también se pueden combinar para que pueda tener múltiples dependencias. Esta funcionalidad proporciona una gran flexibilidad, ya que puede acomodar a las claves externas que dependen de modelos de diferentes aplicaciones.

La opción de definir explícitamente las dependencias entre las migraciones también significa que la numeración de las migraciones (por lo general 0001, 0002, 0003, …) no representa estrictamente el orden en que se aplican las migraciones. Puede añadir cualquier tipo de dependencia que quiere y por lo tanto controlar el orden sin tener que re-número de todas las migraciones.

Visualización de la migración

Por lo general, no tienen que preocuparse por el SQL que generan las migraciones. Pero si desea volver a verificar que el SQL generado tiene sentido o simplemente tienes curiosidad por lo que parece, a continuación, Django tiene todo cubierto con el comando de gestión sqlmigrate:

$ python manage.py sqlmigrate historical_data 0001
BEGIN;
--
-- Create model PriceHistory
--
CREATE TABLE "historical_data_pricehistory" (
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
"date" datetime NOT NULL,
"price" decimal NOT NULL,
"volume" integer unsigned NOT NULL
);
COMMIT;

Hacer que listará a cabo las consultas SQL subyacentes que se generarán por la migración específico, basado en la base de datos en el archivo de settings.py. Cuando se pasa los parámetros –backwards, Django genera el SQL para cancelar la aplicación de la migración:

$ python manage.py sqlmigrate --backwards historical_data 0001
BEGIN;
--
-- Create model PriceHistory
--
DROP TABLE "historical_data_pricehistory";
COMMIT;

Una vez que vea la salida de sqlmigrate para una migración ligeramente más complejo, se puede apreciar que no tiene que diseñar todo esto por SQL ¡mano!

Cómo Django detecta cambios en sus modelos

que has visto lo que un archivo de migración se parece y cómo su lista de clases de operación define los cambios realizados a la base de datos. Pero ¿cómo funciona exactamente Django sé a qué operaciones deben ir en un archivo de migración? Se podría esperar que Django compara sus modelos a tu base de datos, pero que no es el caso.

Cuando se ejecuta makemigrations, Django hace no inspeccionar su base de datos. Tampoco se compara el archivo de modelo a una versión anterior. En su lugar, Django pasa a través de todas las migraciones que se han aplicado y construye un estado de proyecto de lo que los modelos debe ser similar. Este estado del proyecto se compara con sus definiciones de modelos actuales, y se crea una lista de operaciones, que, cuando se aplica, traería el estado del proyecto hasta la fecha con las definiciones de modelos.

jugando al ajedrez con Django

Se puede pensar en sus modelos como un tablero de ajedrez, y Django es un gran maestro de ajedrez verte jugar contra ti mismo. Pero el gran maestro no vigila todos sus movimientos. El gran maestro sólo se fija en el tablero cuando gritas makemigrations.

Debido a que sólo hay un número limitado de movimientos posibles (y el gran maestro es un gran maestro), que puede llegar a los movimientos que se han producido desde la última vez miró el tablero. Ella toma algunas notas y le permite reproducir hasta que gritas makemigrations nuevo.

Al mirar el tablero de la próxima vez, el gran maestro no recuerda lo que el tablero se veía como la última vez, pero se puede ir a través de sus notas de los movimientos anteriores y construir un modelo mental de lo que el tablero de ajedrez parecía.

Ahora, cuando gritas de migración, el gran maestro se volverá a reproducir todos los movimientos registrados en otro tablero y hacer constar en una hoja de cálculo cuál de sus registros ya han sido aplicadas. Este segundo tablero de ajedrez es su base de datos, y la hoja de cálculo es la tabla django_migrations.

Esta analogía es muy apropiado, ya que ilustra muy bien algunos comportamientos de las migraciones de Django: migraciones

  • Django tratan de ser eficiente: Al igual que el gran maestro asume que usted ha hecho el menor número de movimientos, Django tratar de crear el más eficiente migraciones. Si se agrega un campo denominado A a un modelo, a continuación, cambiar el nombre a B, y makemigrations a continuación, ejecutar, entonces Django creará una nueva migración para agregar un campo denominado B.
  • Django migraciones tienen sus límites: Si comete un montón de antes de dejar que se mueve el aspecto de gran maestro en el tablero de ajedrez, entonces no podría ser capaz de seguir los movimientos exactos de cada pieza. Del mismo modo, Django podría no llegar a la migración correcta si haces demasiados cambios a la vez.
  • Django la migración esperar a que las reglas del juego: Cuando haces algo inesperado, como tomar una pieza al azar fuera del tablero o jugando con las notas, el gran maestro no puede notar al principio, pero tarde o temprano, que va a vomitar sus manos y negarse a continuar. Lo mismo sucede cuando te metes con la tabla django_migrations o cambiar la base de datos de esquema fuera de las migraciones, por ejemplo, mediante la supresión de la tabla de base de datos para un modelo. migraciones

Django tratan de ser eficiente: Al igual que el gran maestro asume que usted ha hecho el menor número de movimientos, Django tratar de crear las migraciones más eficientes. Si se agrega un campo denominado A a un modelo, a continuación, cambiar el nombre a B, y makemigrations a continuación, ejecutar, entonces Django creará una nueva migración para agregar un campo denominado B.

Django migraciones tienen sus límites: Si comete un montón de movimientos antes de dejar que el aspecto de gran maestro en el tablero de ajedrez, entonces ella podría no ser capaz de seguir los movimientos exactos de cada pieza. Del mismo modo, Django podría no llegar a la migración correcta si haces demasiados cambios a la vez.

Django la migración esperar a que las reglas del juego: Cuando haces algo inesperado, como tomar una pieza al azar fuera del tablero o jugando con las notas, el gran maestro no puede notar al principio, pero tarde o temprano, ella vomitar sus manos y se niegan a continuar. Lo mismo sucede cuando te metes con la tabla django_migrations o cambiar la base de datos de esquema fuera de las migraciones, por ejemplo, mediante la supresión de la tabla de base de datos para un modelo.

Comprender SeparateDatabaseAndState

Ahora que usted sabe sobre el estado del proyecto de Django que construye, es el momento para tomar una mirada más cercana a la operación SeparateDatabaseAndState. Esta operación se puede hacer exactamente lo que su nombre indica: se puede separar el estado del proyecto (el modelo mental Django construye) de su base de datos.

SeparateDatabaseAndState se instancia con dos listas de operaciones:

Esta operación le permite hacer cualquier tipo de cambio en su base de datos, pero es su responsabilidad asegurarse de que el estado del proyecto se ajusta a la base de datos después. casos de uso de ejemplo para SeparateDatabaseAndState están moviendo un modelo de una aplicación a otra o la creación de un índice en una base de datos enorme sin tiempo de inactividad.

SeparateDatabaseAndState es una operación avanzada y no se necesitará en su primer día de trabajo con las migraciones y tal vez no del todo. SeparateDatabaseAndState es similar a una operación de corazón. Lleva un poco de riesgo y no es algo que se hace sólo por diversión, pero a veces es un procedimiento necesario para mantener al paciente con vida.

Conclusión

Esto concluye su inmersión profunda en las migraciones de Django. ¡Felicidades! Usted ha cubierto un buen montón de temas avanzados y ahora tienen una comprensión sólida de lo que ocurre bajo el capó de migraciones.

Usted aprendió que:

  • Django realiza un seguimiento de las migraciones aplicados en el cuadro migraciones Django. migraciones
  • Django consisten en archivos de Python plano que contiene una clase de migración.
  • Django sabe que cambia para llevar a cabo las operaciones de la lista de las clases de migración.
  • Django compara sus modelos a un estado de proyecto se construye a partir de las migraciones.

Con este conocimiento, usted está listo para hacer frente a la tercera parte de la serie sobre las migraciones de Django, donde aprenderá cómo utilizar las migraciones de datos de forma segura a hacer cambios de una sola vez a sus datos. ¡Manténganse al tanto!

En este artículo se utiliza el proyecto Django Django bitcoin_tracker construida en Migraciones: Una cartilla. Usted puede volver a crear ese proyecto, trabajando a través de ese artículo o se puede descargar el código fuente:

Descargar Código Fuente: Haga clic aquí para descargar el código para las migraciones de Django proyecta que va a utilizar en este artículo.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *