¿Cómo revertir una migración de rieles fallida? Esperaría que rake db:rollback
deshaga la migración fallida, pero no, revierte la migración anterior (la migración fallida menos uno). Y rake db:migrate:down VERSION=myfailedmigration
tampoco funciona. Me he encontrado con esto varias veces y es muy frustrante. Aquí hay una prueba simple que hice para duplicar el problema:
class SimpleTest < ActiveRecord::Migration
def self.up
add_column :assets, :test, :integer
# the following syntax error will cause the migration to fail
add_column :asset, :test2, :integer
end
def self.down
remove_column :assets, :test
remove_column :assets, :test2
end
end
resultado:
== SimpleTest: migrando ============================================= ======== - add_column (: activos,: prueba,: entero) -> 0.0932 s - add_column (: activo,: error) rastrillo abortado! Ha ocurrido un error, todas las migraciones posteriores canceladas: número incorrecto de argumentos (2 por 3)
ok, retrocedamos:
$ rake db: rollback == AddLevelsToRoles: revirtiendo =========================================== == - remove_column (: roles,: level) -> 0.0778 s == AddLevelsToRoles: revertido (0.0779s) ======================================
eh esa fue mi última migración antes de SimpleTest, no la migración fallida. (Y, oh, sería bueno si el resultado de la migración incluyera el número de versión).
Así que intentemos ejecutar el down para la migración fallida SimpleTest:
$ rake db: migrate: down VERSION = 20090326173033 PS
No pasa nada y tampoco hay salida. ¿Pero tal vez ejecutó la migración de todos modos? Así que corrijamos el error de sintaxis en la migración de SimpleTest e intentemos ejecutarlo nuevamente.
$ rake db: migrate: up VERSION = 20090326173033 == SimpleTest: migrando =========================================== ======== - add_column (: activos,: prueba,: entero) rastrillo abortado! Mysql :: Error: Nombre de columna duplicado 'prueba': ALTER TABLE `assets` ADD` test` int (11)
No Obviamente, migrate: down no funcionó. No está fallando, simplemente no se está ejecutando.
No hay forma de deshacerse de esa tabla duplicada que no sea ingresar manualmente a la base de datos y eliminarla, y luego ejecutar la prueba. Tiene que haber una forma mejor que esa.
fuente
Para ir a una versión específica, simplemente use:
Pero si una migración falla parcialmente, primero tendrá que limpiarla. Una forma sería:
down
método de la migración para deshacer la parteup
que funcionódown
)fuente
Bien, amigos, así es como realmente lo hacen. No sé de qué están hablando las respuestas anteriores.
Puede migrar hacia abajo y realizar una copia de seguridad nuevamente si desea verificar que lo tiene ahora.
fuente
bundle exec rake db:migrate:redo
. Dará un paso hacia atrás y un paso hacia adelante, para que pueda verificar que su última migración se ejecuta completamente. Esta es una buena práctica siempre que tenga que impulsar una migración junto con algunas actualizaciones de código.Estoy de acuerdo en que debería usar PostgreSQL cuando sea posible. Sin embargo, cuando está atascado con MySQL, puede evitar la mayoría de estos problemas probando primero su migración en su base de datos de prueba:
Puede volver al estado anterior e intentarlo de nuevo con
rake db:schema:load RAILS_ENV=test
fuente
En 2015 con Rails 4.2.1 y MySQL 5.7, una migración fallida no se puede solucionar con las acciones de rake estándar que proporciona Rails, como sucedió en 2009.
MySql no admite la reversión de declaraciones DDL (en el Manual de MySQL 5.7 ). Y Rails no puede hacer nada con eso.
Además, podemos comprobar cómo Rails está haciendo el trabajo: una migración está envuelta en una transacción dependiendo de cómo responda el adaptador de conexión
:supports_ddl_transactions?
. Después de una búsqueda de esta acción en la fuente de rieles (v 4.2.1), descubrí que solo Sqlite3 y PostgreSql admiten transacciones y, de forma predeterminada , no son compatibles.Editar Por lo tanto, la respuesta actual a la pregunta original: una migración de MySQL fallida debe arreglarse manualmente.
fuente
La forma más sencilla de hacer esto es incluir todas sus acciones en una transacción:
class WhateverMigration < ActiveRecord::Migration def self.up ActiveRecord::Base.transaction do ... end end def self.down ActiveRecord::Base.transaction do ... end end end
Como señaló Luke Francl, "MySql [las tablas MyISAM no] admiten transacciones", por lo que podría considerar evitar MySQL en general o al menos MyISAM en particular.
Si está utilizando InnoDB de MySQL, lo anterior funcionará bien. Cualquier error en up o down se revertirá.
TENGA EN CUENTA que algunos tipos de acciones no se pueden revertir mediante transacciones. Por lo general, los cambios de tabla (eliminar una tabla, eliminar o agregar columnas, etc.) no se pueden deshacer.
fuente
Ejecute solo la migración descendente desde la consola:
http://gilesbowkett.blogspot.com/2007/07/how-to-use-migrations-from-console.html (haga clic en su pastie)
fuente
Tuve un error tipográfico (en "add_column"):
y luego su problema (no se puede deshacer la migración parcialmente fallida). después de algunas búsquedas fallidas en Google, ejecuté esto:
como puede ver, acabo de agregar la línea de corrección a mano y luego la quité nuevamente, antes de registrarla.
fuente
La respuesta de Alejandro Babio anterior proporciona la mejor respuesta actual.
Un detalle adicional que quiero agregar:
Cuando la
myfailedmigration
migración falla, no se considera aplicada, y esto se puede verificar ejecutandorake db:migrate:status
, lo que mostraría un resultado similar al siguiente:$ rake db:migrate:status database: sample_app_dev Status Migration ID Migration Name -------------------------------------------------- up 20130206203115 Create users ... ... down 20150501173156 Test migration
El efecto residual de
add_column :assets, :test, :integer
ser ejecutado en la migración fallida tendrá que revertirse a nivel de base de datos con unaalter table assets drop column test;
consulta.fuente