En Heroku, ¿existe algún peligro en una migración de Django syncdb/South después de que la instancia ya se haya reiniciado con un código de modelo modificado?
django-south (4)
El método recomendado es este:
- Agregue cambios de base de datos para sus nuevas funciones a su código existente
- Hacer que el código existente sea compatible con el nuevo esquema.
- Desplegar
- Añade las nuevas características a tu código base
- Desplegar
Esto significa que los cambios en su base de datos ya están en su lugar cuando el código comienza a requerirlos.
Sin embargo....
Hay un par de problemas con esto. Primero, no conozco ninguna tienda de desarrollo que esté lo suficientemente organizada para poder manejar esto, ya que las características simplemente se construyen ad-hoc, y en segundo lugar, que realmente no se está guardando nada.
En términos generales, a menos que realice grandes cambios en una base de datos masiva, los cambios no tardarán en aplicarse y, por lo general, se terminan en un par de segundos en los que un desarrollador puede trabajar para reiniciar los reinicios, etc. cuando sea necesario. El riesgo es que un usuario pueda obtener una página de error. Si los cambios son más grandes, tienes algunas alternativas. Uno está usando el modo de mantenimiento para apagar el sitio por unos segundos.
Para ser honesto, no hay una manera clara de cómo manejar esto bien, ya que, por definición, su código debe estar implementado para que comiencen los cambios en la base de datos. La mejor manera que he encontrado para abordar el problema es mirar cada cambio individualmente y encontrar el camino más cómodo para cada caso, caso por caso.
Ensayar las implementaciones en un entorno de prueba mitigará el riesgo de que una implementación no funcione correctamente y le dará una idea del impacto.
En Heroku, tan pronto como presiona un nuevo código, las instancias de servicio web se reinician ... incluso si las adiciones / cambios subyacentes del esquema de la base de datos (a través de syncdb o south migrate) aún no se han aplicado.
En muchos casos, esto podría causar errores inofensivos hasta que syncdb / migrate se ejecute poco después. Pero me preocupa que, en algunos casos, el nuevo código pueda trabajar a medias realizando cambios inesperados en la base de datos previa a la migración.
¿Cuál es la forma correcta de estar a salvo de este riesgo?
Una técnica podría ser agregar syncdb / migrate al Procfile para que se ejecute antes de reiniciar la web. Pero, en el caso de varias instancias, o tal vez incluso un caso donde la instancia de código antiguo se deja ejecutando hasta el momento en que se conoce la instancia de código nuevo, todavía hay una variante del problema donde el código es hablando con una base de datos con un esquema no coincidente.
¿Existe una función ''mantener todas las instancias web'' (o la mejor práctica común) para permitir que la migración se complete sin tráfico web?
¿O me preocupa demasiado un riesgo que es insignificante en la práctica?
Heroku lanzó recientemente " buildpacks ", que son los scripts que utilizan para configurar un entorno para su aplicación, desde la gestión de dependencias hasta el reinicio de las instancias. Esencialmente es un Procfile
más completo que puedes personalizar.
Puede bifurcar el buildpack de Python y modificar el script para que se ejecute en la secuencia que desee. Agregue el comando que ejecuta para syncdb
al final de bin/steps/django
. Comprométete y pon este repo en Github.
Lamentablemente, a partir de ahora no es posible modificar el buildpack de una aplicación Heroku existente, por lo que tendrá que eliminarlo y volver a crear uno que apunte a su repositorio de buildpack:
heroku create --stack cedar --buildpack [email protected]:...
Esta es la mejor solución porque
- No cuesta nada en absoluto.
- No requiere que adaptes tu código a Heroku
- Solo sincroniza la base de datos una vez por implementación
Espero que esto ayude.
La manera más segura de manejar las migraciones de esta naturaleza, Heroku o no, es adoptar estrictamente un enfoque de compatibilidad con su esquema y código:
- Cada cambio de esquema aditivo o transformativo debe ser compatible con versiones anteriores;
- Cada cambio de esquema destructivo debe realizarse después de que se haya eliminado el código que depende de él;
- Cada cambio de código debe ser:
- duradero ante la posibilidad de que aún no se hayan realizado cambios de esquema asociados (por ejemplo, eliminar un modelo o un campo en un modelo) o
- realizado solo después de que se haya realizado el cambio de esquema asociado (agregar un modelo o un campo en un modelo)
Si necesita realizar una transformación significativa de un modelo, este enfoque podría requerir los siguientes pasos:
- Cree una nueva tabla de base de datos para mantener su nueva estructura de modelo e implemente esa migración
- Cree un nuevo modelo con la nueva estructura y el código para copiar los cambios del modelo anterior al nuevo modelo cuando cambie el modelo anterior, e implemente ese código
- Ejecute una acción de migración o código para copiar todos los datos del modelo anterior al nuevo modelo
- Actualice su base de código para usar el modelo nuevo en lugar del modelo anterior, borre el modelo anterior e implemente ese código
- Ejecute una migración para eliminar la estructura del modelo anterior de la base de datos
Con un poco de pensamiento y planificación, también se puede utilizar para cambios más drásticos:
- Implemente código que elimine por completo la dependencia de una sección de la base de datos, presumiblemente reemplazando esas secciones del sitio con páginas de mantenimiento
- Implemente una migración que realice cambios drásticos que, por cualquier motivo, no funcionarían con el flujo de trabajo del modelo dual anterior.
- Implemente el código que devuelve las secciones afectadas con la nueva estructura de modelo admitida
Esto puede ser difícil de organizar y requiere una disciplina estricta y una comprensión firme de la interacción de su código con su base de datos, pero en la práctica, permite que la mayoría de los cambios se realicen sin más tiempo de inactividad que el reinicio del servidor.
Parece que los cambios rápidos en la base de datos son el camino a seguir, pero requiere una base de datos dedicada.
http://devcenter.heroku.com/articles/fast-database-changeovers
Alternativamente, aquí hay un tutorial para copiar los datos de una base de datos (p. Ej., Producción) a otra base de datos (p. Ej., Estadificación), realizar la migración de esquema / datos (p. Ej., Usar django / sur) y luego cambiar la aplicación para usar la nueva instancia de base de datos actualizada.
http://devcenter.heroku.com/articles/migrating-data-between-plans
Parece razonable, pero potencialmente lento si hay una gran cantidad de datos.