Wie kann man eine fehlgeschlagene Schienenmigration rückgängig machen? Ich würde erwarten, dass rake db:rollback
würde die fehlgeschlagene Migration rückgängig machen, aber nein, es wird die vorherige Migration zurückgesetzt (die fehlgeschlagene Migration minus eins). Und rake db:migrate:down VERSION=myfailedmigration
funktioniert auch nicht. Ich habe das schon ein paar Mal erlebt, und es ist sehr frustrierend. Hier ist ein einfacher Test, den ich gemacht habe, um das Problem zu duplizieren:
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
Ergebnis:
\== SimpleTest: migrating =====================================================
-- add\_column(:assets, :test, :integer)
-> 0.0932s
-- add\_column(:asset, :error)
rake aborted!
An error has occurred, all later migrations canceled:
wrong number of arguments (2 for 3)
Okay, wir drehen es zurück:
$ rake db:rollback
== AddLevelsToRoles: reverting ===============================================
-- remove\_column(:roles, :level)
-> 0.0778s
== AddLevelsToRoles: reverted (0.0779s) ======================================
Das war meine letzte Migration vor SimpleTest, nicht die fehlgeschlagene Migration. (Und oh, es wäre schön, wenn die Migrationsausgabe die Versionsnummer enthalten würde).
Versuchen wir also, den SimpleTest für die fehlgeschlagene Migration auszuführen:
$ rake db:migrate:down VERSION=20090326173033
$
Es passiert nichts, und es wird auch nichts ausgegeben. Aber vielleicht wurde die Migration trotzdem durchgeführt? Beheben wir also den Syntaxfehler in der SimpleTest-Migration und versuchen wir, sie erneut auszuführen.
$ rake db:migrate:up VERSION=20090326173033
== SimpleTest: migrating =====================================================
-- add\_column(:assets, :test, :integer)
rake aborted!
Mysql::Error: Duplicate column name 'test': ALTER TABLE \`assets\` ADD \`test\` int(11)
Nö. Offensichtlich hat migrate:down nicht funktioniert. Es schlägt nicht fehl, es wird nur nicht ausgeführt.
Es gibt keine andere Möglichkeit, diese doppelte Tabelle loszuwerden, als manuell in die Datenbank zu gehen und sie zu entfernen, und dann den Test durchzuführen. Es muss einen besseren Weg als das geben.