database - mysqlclient - Alterar las tablas de la base de datos en Django
multiple database django (8)
Estoy considerando usar Django para un proyecto que estoy comenzando (fyi, un juego basado en navegador) y una de las características que más me gusta es usar syncdb
para crear automáticamente tablas de base de datos basadas en los modelos de Django que defino ( una característica que no puedo encontrar en ningún otro marco). Ya estaba pensando que esto era demasiado bueno para ser cierto cuando vi esto en la documentación :
Syncdb no alterará las tablas existentes
syncdb solo creará tablas para modelos que aún no se han instalado. Nunca emitirá sentencias ALTER TABLE para hacer coincidir los cambios realizados en una clase de modelo después de la instalación. Los cambios en las clases de modelos y los esquemas de la base de datos a menudo implican cierta ambigüedad y, en esos casos, Django tendría que adivinar los cambios correctos que debe realizar. Existe el riesgo de que se pierdan datos críticos en el proceso.
Si ha realizado cambios en un modelo y desea modificar las tablas de la base de datos para que coincidan, utilice el comando sql para mostrar la nueva estructura SQL y compárela con su esquema de tabla existente para resolver los cambios.
Parece que la alteración de tablas existentes tendrá que hacerse "a mano".
Lo que me gustaría saber es la mejor manera de hacer esto. Dos soluciones vienen a la mente:
- Como sugiere la documentación, realice los cambios manualmente en el DB;
- Haz una copia de seguridad de la base de datos, límpiala, crea las tablas nuevamente (con syncdb, ya que ahora crea las tablas desde cero) e importa los datos de la copia de seguridad (esto puede llevar demasiado tiempo si la base de datos es grande)
¿Algunas ideas?
Como se menciona en otras respuestas al mismo tema, asegúrese de ver el Panel de evolución del esquema DjangoCon 2008 en YouTube.
Además, dos nuevos proyectos en el mapa: Simplemigrations y Migratory .
Django 1.7 (actualmente en desarrollo) está agregando soporte nativo para la migración de esquema con manage.py migrate
y manage.py makemigrations
( syncdb
deprecates syncdb
).
El libro de Django explica cómo hacerlo a mano.
http://www.djangobook.com/es/2.0/chapter10/
Lo he hecho de esta manera muchas veces, y es muy flexible, lo que te permite dejar datos en las tablas mientras los quitas del modelo.
Empecé a usar South recientemente. Parece un poco menos flexible (o tal vez solo necesite leer los documentos un poco más). Pero puede ahorrarte un poco de tipeo. A veces logras desconectarlo de la base de datos, lo cual es una pesadilla. Parece ir bien siempre y cuando lo sigas usando. Parece que une los modelos y la base de datos real, lo que puede o no ser bueno dependiendo de tu situación.
Hacer manualmente los cambios SQL y volcar / volver a cargar son ambas opciones, pero también es posible que desee verificar algunos de los paquetes de esquema de evolución para Django. Las opciones más maduras son django-evolution y South .
EDITAR : Y oye, aquí viene la migración .
ACTUALIZACIÓN : desde que esta respuesta fue escrita originalmente, django-evolution y dmigrations han dejado de desarrollarse activamente y South se ha convertido en el estándar de facto para la migración de esquema en Django. Partes de South incluso pueden integrarse en Django en la próxima versión o dos.
ACTUALIZACIÓN : Un marco de migración de esquemas basado en South (y escrito por Andrew Godwin, autor de South) está incluido en Django 1.7+.
Hasta ahora, en mi compañía, hemos utilizado el enfoque manual. Lo que funciona mejor para usted depende mucho de su estilo de desarrollo.
En general, no tenemos tantos cambios de esquema en los sistemas de producción y despliegues algo formalizados desde el desarrollo hasta los servidores de producción. Cada vez que nos desplegamos (10-20 veces al año) hacemos un fill diff de la rama de producción actual y la venidera revisando todo el código y anotando qué se debe cambiar en el servidor de producción. Los cambios requeridos pueden ser dependencias adicionales, cambios en el archivo de configuración y cambios en la base de datos.
Esto funciona muy bien para nosotros. Tenerlo todo automatizado es una visión de nicho pero difícil para nosotros, tal vez podríamos gestionar las migraciones, pero aún tendríamos que manejar bibliotecas adicionales, servidores, dependencias cualesquiera.
He estado usando django-evolution. Las advertencias incluyen:
- Sus sugerencias automáticas han sido uniformemente podridas; y
- Su función de huella digital devuelve diferentes valores para la misma base de datos en diferentes plataformas.
Dicho esto, me parece práctico el enfoque personalizado schema_evolution.py
. Para evitar el problema de la huella digital, sugiero un código como:
BEFORE = ''fv1:-436177719'' # first fingerprint
BEFORE64 = ''fv1:-108578349625146375'' # same, but on 64-bit Linux
AFTER = ''fv1:-2132605944''
AFTER64 = ''fv1:-3559032165562222486''
fingerprints = [
BEFORE, AFTER,
BEFORE64, AFTER64,
]
CHANGESQL = """
/* put your SQL code to make the changes here */
"""
evolutions = [
((BEFORE, AFTER), CHANGESQL),
((BEFORE64, AFTER64), CHANGESQL)
]
Si tuviera más huellas dactilares y cambios, volvería a factorizarlo. Hasta entonces, hacerlo más limpio sería robar el tiempo de desarrollo de otra cosa.
EDITAR: dado que estoy construyendo manualmente mis cambios de todos modos, intentaré migraciones la próxima vez.
Una buena forma de hacerlo es a través de accesorios, particularmente los accesorios initial_data
.
Un accesorio es una colección de archivos que contienen los contenidos serializados de la base de datos. Por lo tanto, es como tener una copia de seguridad de la base de datos, pero Django es consciente de que es más fácil de usar y tendrá beneficios adicionales cuando realice tareas como pruebas unitarias.
Puede crear un dispositivo a partir de los datos actualmente en su base de datos usando django-admin.py dumpdata
. Por defecto, los datos están en formato JSON, pero otras opciones como XML están disponibles. Un buen lugar para almacenar accesorios es un subdirectorio de fixtures
de sus directorios de aplicaciones.
Puede cargar una solución utilizando django-admin.py loaddata
pero, lo que es más importante, si su dispositivo tiene un nombre como initial_data.json
se cargará automáticamente cuando haga un syncdb
, ahorrándose la molestia de importarlo usted mismo.
Otro beneficio es que cuando ejecuta la manage.py test
para ejecutar sus pruebas unitarias, la base de datos de prueba temporal también tendrá cargado el accesorio de datos iniciales.
Por supuesto, esto funcionará cuando estés agregando atributos a modelos y columnas al DB. Si suelta una columna de la base de datos, deberá actualizar su dispositivo para eliminar los datos de esa columna, lo que podría no ser sencillo.
Esto funciona mejor cuando se hacen muchos pequeños cambios en la base de datos durante el desarrollo. Para actualizar los DB de producción, un script SQL generado manualmente puede funcionar mejor.
django-command-extensions es una biblioteca django que proporciona algunos comandos adicionales para manage.py. Uno de ellos es sqldiff, que debería darle el sql necesario para actualizar a su nuevo modelo. Sin embargo, está catalogado como ''muy experimental''.