2010-11-12 18 views
39

Estoy programando una aplicación web usando sqlalchemy. Todo fue sencillo durante la primera fase de desarrollo cuando el sitio no estaba en producción. Podría cambiar fácilmente el esquema de la base de datos simplemente borrando la vieja base de datos sqlite y creando una nueva desde cero.¿Cómo administrar eficientemente los cambios de esquema frecuentes usando sqlalchemy?

Ahora el sitio está en producción y necesito preservar los datos, pero aún quiero mantener mi velocidad de desarrollo original convirtiendo fácilmente la base de datos al nuevo esquema.

Digamos que tengo model.py en la revisión 50 y model.py una revisión 75, que describe el esquema de la base de datos. Entre esos dos esquemas, la mayoría de los cambios son triviales, por ejemplo, una nueva columna se declara con un valor predeterminado y solo deseo agregar este valor predeterminado a los registros anteriores.

Eventualmente, algunos cambios pueden no ser triviales y requieren algunos cálculos previos.

¿Cómo maneja (o manejaría) las aplicaciones web que cambian rápidamente con, por ejemplo, una o dos versiones nuevas del código de producción por día?

Por cierto, el sitio está escrito en Pilones si esto hace alguna diferencia.

+1

"Así es vale la pena usar migrate? " debería ser una pregunta separada. Usted tiene una respuesta sobre cómo migrar. Preguntar acerca de los casos de uso para sqlalchemy-migrate y su caso de uso específico es más específico que esta pregunta general. –

+1

OK, así que necesito hacer otra pregunta sobre la migración para saber qué respuesta aceptar. – ascobol

+1

@ascobol: "otra pregunta sobre migrar para saber qué respuesta aceptar". Falso. Tienes respuestas aquí. "¿Valora la herramienta [X]?" no está relacionado con "¿cómo migro?". Usted tiene respuestas a "¿cómo?". Preguntar sobre el valor de una herramienta en particular no está relacionado con "¿cómo?" –

Respuesta

33

Alembic es una nueva herramienta de migración de bases de datos, escrita por el autor de SQLAlchemy. Me pareció mucho más fácil de usar que sqlalchemy-migrate. También funciona a la perfección con Flask-SQLAlchemy.

Auto generar el script de migración de esquema a partir de sus modelos SQLAlchemy:

alembic revision --autogenerate -m "description of changes" 

A continuación, aplicar los nuevos cambios en el esquema de base de datos:

alembic upgrade head 

Más información aquí: http://readthedocs.org/docs/alembic/

+0

Estoy de acuerdo, pero es un poco difícil hacerlo funcionar con su aplicación de matraz. Creo que el nuevo código 'frasco-alambique' es lo que necesito probar. Compruebe este problema: http://stackoverflow.com/questions/14682466/relative-importing-python-module-from-a-subfolder-from-a-different-subfolder#comment20531813_14682466 – Dexter

+2

Después de ejecutar 'alambic init alambic' y cambiar mi nombre de usuario de db y contraseña en alembic.ini, cambié mi alambic/env.py a este: https://gist.github.com/alanhamlett/4721073 Eso era todo lo que se necesitaba para hacer funcionar el alambique con mi aplicación de matraz . Espero eso ayude. –

+0

mi problema es que no puedo hacer la línea 10 en tu código esencial. No puedo importar mis modelos o mi variable "db". No me dejará hacerlo en env.py. – Dexter

12

Lo que hacemos.

  1. Utilice la "versión principal". "Versión secundaria" identificación de sus aplicaciones. La versión principal es el número de versión del esquema. El número principal no es un tipo aleatorio de "suficiente funcionalidad nueva". Es una declaración formal de compatibilidad con el esquema de la base de datos.

    Release 2.3 y 2.4 tanto en la versión utilización del esquema 2.

    versión 3.1 utiliza el esquema de la versión 3.

  2. Haga que la versión del esquema sea muy, muy visible. Para SQLite, esto significa mantener el número de versión del esquema en el nombre del archivo de la base de datos. Para MySQL, use el nombre de la base de datos.

  3. Escribir scripts de migración. 2to3.py, 3to4.py. Estas secuencias de comandos funcionan en dos fases. (1) Consulta los datos antiguos en la nueva estructura creando archivos CSV o JSON simples. (2) Cargue la nueva estructura desde los archivos simples CSV o JSON sin procesamiento adicional. Estos archivos de extracción, debido a que están en la estructura adecuada, son rápidos de cargar y pueden usarse fácilmente como accesorios de prueba de la unidad. Además, nunca tiene dos bases de datos abiertas al mismo tiempo. Esto hace que los scripts sean un poco más simples. Finalmente, los archivos de carga se pueden usar para mover los datos a otro servidor de base de datos.

Es muy, muy difícil "automatizar" la migración de esquemas. Es fácil (y común) tener una cirugía de base de datos tan profunda que un script automatizado no puede mapear fácilmente los datos del esquema anterior al nuevo esquema.

+0

¿Cómo se define un cambio de esquema principal? ¿Es la adición de una tabla/nuevo modelo considerada un cambio de esquema principal, incluso si la compatibilidad no cambió? ¿Eres rival de Firefox en los números de versión? (broma) – Dexter

12

Use sqlalchemy-migrate.

Está diseñado para admitir un enfoque ágil del diseño de la base de datos y facilitar la sincronización de las bases de datos de desarrollo y producción, ya que se requieren cambios en el esquema. Hace versiones de esquema fáciles.

Piense en ello como un control de versión para su esquema de base de datos. Usted le asigna cada cambio de esquema y podrá avanzar o retroceder en las versiones de esquema. De esta forma, puede actualizar un cliente y sabrá exactamente qué conjunto de cambios aplicar en la base de datos de ese cliente.

Hace lo que S.Lott propone en su respuesta, automáticamente para usted. Hace que lo difícil sea fácil.

0

La mejor manera de resolver su problema es reflejar su esquema en lugar de hacerlo de manera declarativa. Escribí un artículo sobre el enfoque reflexivo aquí: http://petrushev.wordpress.com/2010/06/16/reflective-approach-on-sqlalchemy-usage/ pero también hay otros recursos sobre esto. De esta manera, cada vez que realice cambios en su esquema, todo lo que necesita hacer es reiniciar la aplicación y la reflexión obtendrá los nuevos metadatos para los cambios en las tablas. Esto es bastante rápido y sqlalchemy lo hace solo una vez por proceso. Por supuesto, tendrás que gestionar los cambios de relaciones que hagas tú mismo.

+5

Solo para comentar, esta es una práctica horrible en el mundo real. Me obliga a verificar la base de datos frente al código para todo tipo de configuraciones, como longitudes permitidas en cadenas, etc. No obtengo ningún autocompletado ni comprobaciones de origen desde mi IDE. Realmente desanimo a las personas de ir a reflexionar en cualquier proyecto. Es un desastre trabajar con eso. – Rick

+2

"todo tipo de configuraciones, como las longitudes permitidas en las cadenas" - ¿puedes dar más detalles sobre esto? ¿Qué tipo de configuraciones? Y, el hecho de que no obtenga autocompletar en ide no significa que el enfoque sea incorrecto. Después de todo, estamos lidiando con python, no java/C++. – vonPetrushev

+0

Además, tengo aplicaciones 'en el mundo real' que funcionan con db reflection. Con complejos ER. No es tan complicado para mí. – vonPetrushev

Cuestiones relacionadas