2009-09-28 8 views
42

A medida que avance en las iteraciones de mi aplicación * (s) acumulo migraciones. A partir de ahora hay 48 archivos de este tipo, que abarcan alrededor de 24 meses de actividad.¿Cuándo (si) consolida las migraciones de ActiveRecord?

Estoy considerando tomar mi actual schema.rb y hacer que la línea de base.

También estoy considerando eliminar (sujeto al control de la fuente, por supuesto) las migraciones existentes y crear una nueva y única y brillante migración desde mi esquema actual. A las migraciones les gustan los símbolos, pero rake db:schema:dump usa cadenas: ¿me debería importar?

¿Eso parece sensato? Si es así, ¿en qué tipo de intervalo tendría sentido tal ejercicio? Si no, ¿por qué no?

¿Y estoy perdiendo alguna tarea (¿rake?) Que haría esto por mí?

* En mi caso, todas las aplicaciones están basadas en Rails, pero cualquier cosa que use migraciones de ActiveRecord parece encajar con la pregunta.

+0

Mike, ¿usa anotar? http://weblog.rubyonrails.org/2006/3/3/annotated-models soluciona la mayor parte de la razón para querer hacer esto en primer lugar –

Respuesta

34

Sí, esto tiene sentido. Existe una práctica de consolidación de migraciones. Para hacerlo, simplemente copie el esquema actual en una migración y elimine todas las migraciones anteriores. Entonces tiene menos archivos para administrar y las pruebas pueden ejecutarse más rápido. Debe tener cuidado haciendo esto, especialmente si tiene migraciones que se ejecutan automáticamente en producción. En general, reemplazo una migración que sé que todos han ejecutado con el nuevo esquema.

Otras personas tienen formas ligeramente diferentes de hacer esto.

En general, no he hecho esto hasta que tuvimos más de 100 migraciones, pero podemos lograrlo después de unos meses de desarrollo. Sin embargo, a medida que el proyecto madura, las migraciones son cada vez menos frecuentes, por lo que es posible que no tenga que volver a hacerlo.

Esto va en contra de una buena práctica: una vez que compruebe una migración al control de origen, no lo modifique. Hago una rara excepción si hay un error en uno, pero esto es bastante raro (1 en 100 tal vez). La razón es que una vez que están en libertad, algunas personas pueden haberlos ejecutado. Se registran como completados en el db. Si los modifica y registra una nueva versión, otras personas no obtendrán el beneficio del cambio. Puede pedirle a la gente que retroceda ciertos cambios y volver a ejecutarlos, pero eso frustra el propósito de la automatización. Hecho a menudo, se convierte en un desastre. Es mejor dejarlo solo.

+0

Entonces, por ejemplo, una vez que haya ejecutado una migración a la producción, ¿por qué querría seguir ejecutando las migraciones anteriores? Para configurar un nuevo DB, para un nuevo entorno de desarrollo/prueba, digamos que debería simplemente db: schema: cargar a la línea base y luego ejecutar nuevas migraciones. Eso parece sensato. Siempre tendré las migraciones originales en versiones anteriores, después de todo. –

+0

Nuestro entorno de prueba automatizado realiza un DB: restablece y ejecuta todas las migraciones antes de cada conjunto de pruebas, y ese es realmente el único momento en que las migraciones se ejecutan completamente, donde las migraciones de rehacer son muy útiles. Las personas las limpian solo para reducir la cantidad de archivos. Ciertamente, el db: schema: load funcionaría ... Creo que la idea detrás de esto es que obtenga algunas pruebas de las migraciones como parte de la integración continua. – ndp

7

Creo que hay dos tipos de migraciones:

  • los que usted hizo durante el diseño/desarrollo, ya que ha cambiado de opinión sobre cómo su base de datos debería ser así;

  • las que realizó entre lanzamientos, lo que refleja algunos cambios de comportamiento.

me libro de la primera clase de migraciones tan pronto como pueda, ya que no representan realmente los comunicados de trabajo y mantener la segunda clase, por lo que es posible, en teoría, para actualizar la aplicación .

Acerca de símbolos vs cadenas: muchos argumentan que solo se deben usar cadenas en migraciones: los símbolos están destinados a ser "manejadores" de objetos y no deben usarse para representar nombres (nombres de columnas y tablas, en este caso). Esta es una mera consideración estilística, pero me convenció y ya no utilizo símbolos en las migraciones.

He leído de otro punto para usar cadenas: "símbolos ruby ​​son pérdidas de memoria", lo que significa que, cuando crea un símbolo, nunca se elimina durante toda la vida útil de la aplicación. Esto me parece completamente inútil, ya que todas sus columnas db se usarán como símbolos en una aplicación Rails (y ActiveRecord); la tarea de migrar tampoco durará para siempre, así que no creo que este punto tenga sentido.

+0

Solo una nota al azar con respecto a los símbolos/cadenas: Si un símbolo es utilizado 10 veces, solo ocupa la memoria una vez. Cuando se utiliza una cadena (asumiendo una cadena literal) ocupa la memoria requerida cada vez que está en el código. Entonces, el símbolo podría nunca obtener GC, solo hay uno alrededor. –

0

No debería estar borrando migraciones. ¿Por qué crear el trabajo extra?

Las migraciones son básicamente un conjunto de instrucciones que definen cómo crear la base de datos para admitir su aplicación. A medida que construyes tu aplicación, las migraciones registran los cambios iterativos que realizas en la base de datos.

En mi humilde opinión al restablecer la línea de base periódicamente, usted está realizando cambios que tienen el potencial de introducir errores/problemas con su aplicación, creando trabajo adicional.

En el caso de que una columna se agregue por error y luego necesite ser eliminada en algún momento, solo cree una nueva migración para eliminar la columna adicional. Mi razón principal para esto es que cuando trabajas en un equipo no quieres que tus colegas tengan que seguir reconstruyendo sus bases de datos desde cero.Con este enfoque simple, usted (y ellos) pueden seguir trabajando de manera iterativa.

Como nota adicional: cuando se construye una nueva base de datos desde cero (sin ningún dato), las migraciones tienden a ejecutarse muy rápidamente. Un proyecto en el que estoy trabajando actualmente tiene 177 migraciones, esto no causa problemas al construir una nueva base de datos.

1

aunque estoy seguro de todo el mundo tiene sus propias prácticas, hay algunas reglas que implica la forma en que funciona el sistema de migración:

  • Nunca confirmó cambios en las migraciones que pueden haber sido utilizados por otros desarrolladores o despliegues anteriores . En su lugar, realice una migración adicional para ajustar las cosas según sea necesario.
  • Nunca coloque dependencias a nivel de modelo en una migración. El modelo puede ser renombrado o eliminado en algún momento en el futuro y esto evitaría la migración. Mantenga la migración lo más autónoma posible, incluso si eso significa que es bastante simple y de bajo nivel.

Por supuesto que hay excepciones. Por ejemplo, si una migración no funciona, por la razón que sea, es posible que se necesite un parche para actualizarla. Incluso entonces, sin embargo, la naturaleza de los cambios efectuados por la migración no debería cambiar, aunque la implementación de los mismos sí puede cambiar.

Cualquier proyecto de Rails maduro probablemente tendrá alrededor de 200 a 1000 migraciones. En mi experiencia, es inusual ver un proyecto con menos de 30, excepto en las etapas de planificación. Después de todo, cada modelo generalmente necesita su propio archivo de migración.

Colapsar migraciones múltiples en una sola es un mal hábito para entrar cuando se trabaja en una pieza de software en evolución. Probablemente no colapses el historial de control de origen, entonces ¿por qué preocuparse por el historial de esquemas de la base de datos?

La única ocasión en la que puedo ver que es razonablemente práctico es si está bifurcando un proyecto anterior para crear una nueva versión o derivación y no desea tener que llevar adelante una cantidad extraordinaria de migraciones.

+0

Es probable que un proyecto maduro de cierta complejidad haya pasado por uno o más refactores de base de datos importantes, con migraciones que "ajustan" las cosas para admitir cada refactor. Con el tiempo, estas migraciones relacionadas con el refactorizador pueden volverse problemáticas al ejecutar todas las migraciones de principio a fin. En estas situaciones, es potencialmente ventajoso colapsar las migraciones anteriores. –

+0

Si alguna vez llega al punto en el que tiene "demasiadas" migraciones, siempre puede colapsarlas todas en una instantánea de su actual 'db/schema.rb'. Tenga en cuenta que los proyectos que maduran normalmente requieren una instantánea de base de datos personalizada de todos modos, por lo que el número de personas que migran desde cero debe ser mínimo. A menos que tenga literalmente miles de migraciones, probablemente no valga la pena reescribir la historia. A menudo tiene efectos secundarios no deseados. – tadman

2

La parte superior del esquema.rb declara:

# This file is auto-generated from the current state of the database. Instead of editing this file, 
# please use the migrations feature of Active Record to incrementally modify your database, and 
# then regenerate this schema definition. 
# 
# Note that this schema.rb definition is the authoritative source for your database schema. If you need 
# to create the application database on another system, you should be using db:schema:load, not running 
# all the migrations from scratch. The latter is a flawed and unsustainable approach (the more migrations 
# you'll amass, the slower it'll run and the greater likelihood for issues). 
# 
# It's strongly recommended to check this file into your version control system. 

debo apoyar lo que [Giorgian] dijo anteriormente acerca de las diferentes migraciones para diferentes propósitos. Recomiendo limpiar las migraciones orientadas al desarrollo junto con otras tareas que realiza cuando se ramifica para un lanzamiento. Eso funciona bien para mí, para mí y para los equipos pequeños. Por supuesto, mi aplicación principal se encuentra en la parte superior y entre otras dos bases de datos con sus propios esquemas que tengo que tener cuidado, así que utilizamos migraciones (en lugar de restauración de esquema) para una nueva instalación y esas necesitan sobrevivir ingeniería de lanzamiento.

3

Tener muchas migraciones es algo bueno. En combinación con su sistema de control de versiones, le permiten ver qué desarrollador realizó un cambio en la base de datos y por qué. Esto ayuda con la responsabilidad. Quitarlos solo hace que esto sea una gran molestia.

Si realmente desea obtener una nueva base de datos funcionando rápidamente, puede simplemente cargar el esquema con rake db: schema: cargar RAILS_ENV = your_environment y si desea obtener rápidamente la configuración de la base de datos de prueba, puede usar rake db : prueba: prepare

Dicho esto, si realmente desea consolidar sus migraciones, crearía una nueva migración que verifica si se realizó la última migración en su conjunto (por ej .: la columna agregado existe?) y si no, se disparará. De lo contrario, la migración solo se agregará a la tabla de esquema como completada, por lo que no intentará volver a iniciarse.

Simplemente comunique lo que está haciendo al resto de su equipo para que entiendan lo que está sucediendo, no sea que disparen ciegamente un rastrillo db: migren y arruinen algo que ya tenían.

Cuestiones relacionadas