2011-08-17 8 views
6

Mi estrategia de implementación es el siguiente (utilizando Tela):programación comprobar si hay django migraciones al sur que necesitan ser desplegados

  1. crear un nuevo virtualenv
  2. desplegar nuevo código en la nueva virtualenv
  3. espectáculo una página de mantenimiento
  4. copiar el dB actual a la nueva db
  5. migrar nueva db
  6. punto nuevo código a la nueva db
  7. enlace simbólico virtualenv actual al nuevo Venv
  8. servicios de reinicio
  9. página de mantenimiento quitar

quiero repetir rápido. Ahora, la mayoría de los cambios de código no contienen migraciones. Además, el archivo db está creciendo, por lo que se genera una sobrecarga al copiar la base de datos cada vez que despliegue un cambio (en su mayoría pequeño). Para evitar copiar la base de datos, quiero verificar si hay migraciones que deben implementarse (antes del paso 4). Si no hay migraciones, puedo ir directamente del paso 2 al paso 7. Si las hay, seguiré todos los pasos. Para esto, necesito verificar programáticamente si hay migraciones que deben implementarse. ¿Cómo puedo hacer esto?

Respuesta

5

En el paso 2, mientras se implementa el nuevo código, puede implementar una secuencia de comandos que, cuando se ejecute en el servidor, detectará si hay nuevas migraciones.

Ejemplo código es el siguiente:

# copied mostly from south.management.commands.migrate 
from south import migration 
from south.models import MigrationHistory 

apps = list(migration.all_migrations()) 

applied_migrations = MigrationHistory.objects.filter(app_name__in=[app.app_label() for app in apps]) 
applied_migrations = ['%s.%s' % (mi.app_name,mi.migration) for mi in applied_migrations] 

num_new_migrations = 0 
for app in apps: 
    for migration in app: 
     if migration.app_label() + "." + migration.name() not in applied_migrations: 
      num_new_migrations = num_new_migrations + 1 

return num_new_migrations 

Si envuelve el código anterior en un script, el script de implementación tela puede utilizar la operación de ejecución para obtener el número de nuevas migraciones.

Si esto devuelve cero, puede omitir los pasos asociados con la copia de la base de datos.    

+1

Gracias, Philip, por mostrar el código. Esto es casi exactamente cómo lo implementé. Funciona muy bien, ya ha realizado muchas implementaciones con y sin migraciones con este método. –

1

¿Por qué mueve las bases de datos? El objetivo de las migraciones es aplicar los cambios realizados en el desarrollo a su base de datos de producción.

Sus pasos realmente debe ser:

  1. crear un nuevo virtualenv
  2. desplegar nuevo código en la nueva virtualenv
  3. muestran una página de mantenimiento
  4. migrar nueva db
  5. enlace simbólico virtualenv actual al nuevo venv
  6. reiniciar servicios
  7. eliminar Página de mantenimiento

Y el paso de migración no lleva tanto tiempo si no hay nuevas migraciones reales para ejecutar. Simplemente se ejecutará en cada aplicación diciendo que ya está actualizada.

Si está copiando la base de datos para tener una copia de seguridad, eso es algo que debería estar ejecutándose de todos modos en cron o algo, no como parte de su implementación.

En realidad, estoy confundido sobre la creación de un nuevo virtualenv cada vez también. El normalizada (es decir: más típico) el despliegue es:

  1. desplegar nuevo código
  2. migran db
  3. servicios de reinicio

Si desea volver a añadir en la materia página de mantenimiento, se puede , pero el proceso toma solo un minuto o dos en total.

+0

El objetivo de mi estrategia es poder retroceder rápidamente. Revertir con mi estrategia es solo una cuestión de enlace simbólico al virtualenv anterior que aún apunta a la db derecha. Con su sugerencia, si algo sale mal, está atascado con una base de datos migrada y un virtualenv que es difícil de revertir. Para deshacer la base de datos, necesita una base de datos con copia de seguridad que probablemente no esté actualizada. Además, no se recomienda retroceder con South. Quiero mantener mi estrategia, pero sin copiar y migrar la base de datos, si no hay migraciones. Por lo tanto, mi pregunta sigue en pie. –

+0

¿Por qué no se recomienda retroceder con South? Si configura sus migraciones del sur de forma adecuada, de modo que los datos nunca se eliminen, solo se muevan, entonces es perfectamente kosher revertir una migración. Ese es, literalmente, todo el propósito de las migraciones. –

+0

Pensé que el autor de South (Andrew Godwin) se dijo a sí mismo (Djangocon EU 2011). Sin embargo, podría haberlo malinterpretado. Si no hay problemas reales con la correcta configuración de las migraciones hacia atrás, probablemente debería ir por ese camino. –

3
./manage.py migrate --all --merge --list | grep "()" 

le dirá y mostrará qué migraciones. Si desea un código de retorno o conteo, use wc.

Esto tiene la ventaja de no copiar y pegar código como la respuesta aceptada (que viola DRY), y también si la API interna del sur cambia el código, seguirá funcionando.

ACTUALIZACIÓN:

Django 1.7 cambió la salida de utilizar el soporte en lugar de paréntesis y Django 1.8 introduce un comando showmigration:

./manage.py showmigrations --list | grep '[ ]' 
+1

simple y directo, me gusta esto. – caesarsol

+0

Solo para ser 100% claro: ¿aplicará esto alguna migración no aplicada? ¿O simplemente enumerará las migraciones sin aplicar? –

+0

Solo mostrará una lista y no aplicará nada. Perfectamente seguro. – dalore

1

respuesta de dalore actualizado para Django 1.7+

./manage.py migrate --list | grep "\[ ]" 

Si solo quiere el conteo, entonces:

./manage.py migrate --list | grep "\[ ]" | wc -l 
Cuestiones relacionadas