2009-03-07 12 views

Respuesta

49

Si está trabajando con sistemas de grado de producción entonces sí, es muy malo. Si se trata de su propio proyecto favorito, todo está permitido (si no es así, será una experiencia de aprendizaje), aunque es probable que más pronto que tarde, incluso en un proyecto de mascotas, se encuentre poniendo una cruz sobre un migración inversa sólo para tener que deshacer que la migración a los pocos días, ya sea a través de rake o manualmente.)

en un escenario de producción, debe siempre hacen el esfuerzo de escribir y la prueba una migración reversible en el Si descubrimos un error que lo obliga a retroceder (código y esquema) a alguna revisión anterior (a la espera de alguna solución no trivial, y un sistema de producción que de otro modo sería inutilizable).

migraciones inversas van desde su mayoría trivial (eliminando columnas o tablas que se han añadido durante la migración, y/o el cambio de tipos de columna, etc.) para algo más involucrado (execute de JOIN ed INSERT s o UPDATE s), pero nada es tan complejo como para justificar "barrerlo debajo de la alfombra". Si nada más, forzarse a sí mismo a pensar en formas de lograr migraciones inversas le puede dar una nueva idea del problema que está arreglando su migración hacia adelante.

En ocasiones, puede encontrarse en una situación en la que una migración directa elimina una característica, lo que hace que los datos se descarten de la base de datos. Por razones obvias, la migración inversa no puede reanimar los datos descartados. Aunque uno podría, en tales casos, recomendar que la migración directa guarde automáticamente los datos o mantenerlos en caso de reversión como alternativa a una falla absoluta (guardar en yml, copiar/mover a una tabla especial, etc.), no es necesario, ya que el tiempo requerido para probar dicho procedimiento automatizado podría exceder el tiempo requerido para restaurar los datos manualmente (si fuera necesario) Pero incluso en tales casos, en lugar de simplemente fallar, siempre puede hacer la migración inversa condicionalmente y temporalmente fallar pendiente alguna acción del usuario (es decir, probar la existencia de alguna tabla obligatoria que debe restaurarse manualmente; si falta, salida "He fallado porque no puedo volver a crear la tabla XYZ de la nada; tabla XYZ de la copia de seguridad t ¡Que me corra otra vez, y no te fallaré!")

+0

Una vez que tenga docenas o cientos de migraciones, vale la pena lanzar una excepción también, en el sentido de "ESTO ES IRREVERSIBLE. ¿ESTÁ SEGURO?" –

+0

Puede usar [OffScale DataGrove] (http://off-scale.com) para guardar el estado completo de la base de datos antes de ejecutar una migración. Si alguna vez necesita revertir una migración, puede hacerlo incluso en el caso en que su migración realmente descarte los datos. También puede usarlo para probar migraciones. – Taichman

2

IIRC, tendrá la IrreversibleMigration al cambiar un tipo de datos en la migración.

3

Sentir que necesita una migración irreversible es probablemente una señal de que se avecinan problemas mayores. Tal vez algunos detalles ayudarían?

En cuanto a su segunda pregunta: siempre tomo el "esfuerzo" de escribir el reverso de las migraciones. Por supuesto, I en realidad no escribo el .down, TextMate lo inserta automáticamente al crear el .up.

6

En un escenario de producción, siempre debe hacer el esfuerzo de escribir y probar una migración reversible en el caso de que la realice en producción, luego descubrir un error que lo obliga a retroceder (código y esquema) a alguna revisión anterior (pendiente alguna solución no trivial -. y un sistema de producción de otro modo inutilizable)

tener una migración reversible está muy bien para el desarrollo y la puesta en escena, pero suponiendo código bien probado que debe ser extremadamente rara que alguna vez querrías migrar hacia abajo en producción. Incorporo mis migraciones a una Migración Irreversible automática en modo de producción. Si realmente necesitara revertir un cambio, podría d use otra migración "hacia arriba" o elimine la excepción. Eso parece incompleto sin embargo. Cualquier error que pueda causar un escenario así de alarmante es una señal de que el proceso de garantía de calidad está seriamente arruinado.

+5

O que la empresa es demasiado pequeña para tener un buen proceso de control de calidad, o los gerentes no la admiten. – Tilendor

25

Si está destruyendo datos, primero puede hacer una copia de seguridad. p.

def self.up 
    # create a backup table before destroying data 
    execute %Q[create table backup_users select * from users] 
    remove_column :users, :timezone 
end 

def self.down 
    add_column :users, :timezone, :string 
    execute %Q[update users U left join backup_users B on (B.id=U.id) set U.timezone = B.timezone] 
    execute %Q[drop table backup_users] 
end 
3

Reversible Data Migration hace que sea fácil crear las migraciones de datos reversible mediante archivos YAML.

class RemoveStateFromProduct < ActiveRecord::Migration 
    def self.up 
    backup_data = [] 
    Product.all.each do |product| 
     backup_data << {:id => product.id, :state => product.state} 
    end 
    backup backup_data 
    remove_column :products, :state 
    end 
    def self.down 
    add_column :products, :state, :string 
    restore Product 
    end 
end 
0

Creo que otra situación cuando está bien es cuando tienes una migración consolidada. En ese caso, un "bajón" no tiene sentido, ya que dejaría caer todas las tablas (excepto las tablas agregadas después de la consolidación). Probablemente no sea lo que querrías.

Cuestiones relacionadas