2008-08-30 22 views
59

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 las tablas de la base de datos basado 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 verdad cuando vi esto en el documentation:Alterar las tablas de la base de datos en Django

syncdb no alterará las tablas existentes

syncdb sólo creará tablas para los 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, use 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 modificación de las tablas existentes tendrá que hacerse "a mano".

Lo que me gustaría saber es la mejor manera de hacerlo. Se me ocurren dos soluciones:

  • Como lo sugiere la documentación, realice los cambios manualmente en el DB;
  • Haga una copia de seguridad de la base de datos, límpiela, cree las tablas nuevamente (con syncdb, ya que está creando las tablas desde cero) e importe los datos respaldados (esto puede llevar demasiado tiempo si la base de datos es grande)

¿Alguna idea?

Respuesta

59

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.

EDIT: Y hey, aquí viene dmigrations.

ACTUALIZACIÓN: Dado que esta respuesta fue escrito originalmente, django-evolution y dmigrations tienen tanto cesó desarrollo activo y South 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 migraciones de esquema basado en South (y escrito por Andrew Godwin, autor de South) está incluido en Django 1.7+.

+1

django-evolution parece funcionar bien, gracias! Vale la pena señalar que uno debe comenzar a usarlo desde el principio (no calcula los cambios necesarios del SQL existente). – gatoatigrado

9

Una buena forma de hacerlo es a través de los accesorios, especialmente 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 fixtures de los directorios de sus aplicaciones.

Puede cargar una fijación usando 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 una syncdb, lo que le ahorrará la molestia de importarlo usted mismo.

Otra ventaja es que cuando ejecuta manage.py test para ejecutar sus Pruebas Unitarias, la base de datos de prueba temporal también tendrá cargado el Accesorio de Datos Inicial.

Por supuesto, esto funcionará cuando esté agregando atributos a modelos y columnas a la base de datos. 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.

4

He estado usando django-evolution. Las advertencias incluyen:

  • Sus sugerencias automáticas han sido uniformemente podridas; y
  • Su función de huella digital devuelve valores diferentes para la misma base de datos en diferentes plataformas.

Dicho esto, me parece práctico el enfoque personalizado schema_evolution.py. Para solucionar el problema de huellas digitales, sugiero 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 digitales y los cambios, me re-factor de ella. Hasta entonces, hacerlo más limpio sería robar el tiempo de desarrollo de otra cosa.

EDIT: Dado que estoy construyendo manualmente mis cambios de todos modos, intentaré dmigrations la próxima vez.

+0

Para evoluciones simples como agregar, eliminar o renombrar campos, django-evolution me ha funcionado bien. A veces tengo que agregar un valor predeterminado que preferiría no especificar en el modelo (y más bien decirle a django-evolution que solo lo configure para los campos existentes) pero aparte de eso, no tengo quejas. –

3

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

2

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 los servidores de desarrollo hasta los 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 próxima examinando todo el código y tomando nota de lo que debe cambiarse 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.

2

El libro de Django explica cómo hacerlo a mano.

http://www.djangobook.com/en/2.0/chapter10/

he hecho de esta manera muchas veces, y es muy flexible, que le permite dejar los datos en las tablas, mientras que la eliminación de ellos a partir 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 mientras 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

2

Django 1.7 (actualmente en desarrollo) es adding native support para la migración de esquema con manage.py migrate y manage.py makemigrations (migrate deprecates syncdb).

Cuestiones relacionadas