Frage

Wie rollen Sie wieder ein ausgefallenes Schienen Migration? Ich würde erwarten, dass rake db:rollback würde die fehlgeschlagenen Migration rückgängig machen, aber nein, rollt er die vorherige Migration zurück (die gescheiterte Migration minus eins). Und rake db:migrate:down VERSION=myfailedmigration funktioniert auch nicht. Ich habe in diese ein paar Mal lief und es ist sehr frustrierend. Hier ist ein einfacher Test, den ich gemacht, 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)

ok, lässt Rolle es zurück:

$ rake db:rollback
==  AddLevelsToRoles: reverting ===============================================
-- remove_column(:roles, :level)
   -> 0.0778s
==  AddLevelsToRoles: reverted (0.0779s) ======================================

oder? das war meine letzte Migration vor Simple, nicht die gescheiterte Migration. (Und oh, es wäre schön, wenn die Migration Ausgabe die Versionsnummer enthalten.)

läßt also versuchen, die unten für die ausgefallene Migration Simple ausgeführt wird:

$ rake db:migrate:down VERSION=20090326173033
$

Es passiert nichts, und keine Ausgabe entweder. Aber vielleicht lief es die Migration überhaupt? So kann die Syntaxfehler in der Simple Migration beheben, und versuchen Sie es 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)

Nein. Offensichtlich ist die Migrate: nach unten funktionierte nicht. Es versagt nicht, es ist nur nicht ausgeführt wird.

Auf keinen Fall andere dieser doppelten Tabelle, um loszuwerden, als manuell in die Datenbank gehen und zu entfernen, und dann den Test läuft. Es muss ein besserer Weg, als sein.

War es hilfreich?

Lösung

Leider müssen Sie manuell bereinigen fehlgeschlagen Migrationen für MySQL. MySQL nicht transaktionalen Datenbankdefinition Änderungen unterstützen.

Rails 2.2 Transaktions Migrationen für PostgreSQL enthält. Rails 2.3 beinhaltet Transaktions Migrationen für SQLite.

Dies ist wirklich nicht Sie für Ihr Problem helfen gerade jetzt, aber wenn Sie eine Auswahl der Datenbank über zukünftige Projekte haben, ich empfehlen, eine mit Unterstützung für Transaktions DDL, weil es Migrationen viel angenehmer macht.

Update - das ist im Jahr 2017 immer noch wahr, auf Rails 4.2.7 und MySQL 5.7, von Alejandro Babio in einer anderen Antwort hier berichtete

.

Andere Tipps

Um auf eine bestimmte Version gehen Sie einfach verwenden:

rake db:migrate VERSION=(the version you want to go to)

Aber wenn eine Migration teilweise ausfällt, werden Sie es aufzuräumen zuerst müssen. Eine Möglichkeit wäre:

  • bearbeiten Sie die down Methode der Migration nur den Teil des up rückgängig machen, die gearbeitet
  • wandern zurück zum vorherigen Zustand (wo Sie begonnen haben)
  • fixiert die Migration (einschließlich zum Verhängnis Ihrer Änderungen an den down)
  • versuchen Sie es erneut

OK, Leute, hier ist, wie Sie es wirklich tun. Ich weiß nicht, was die oben genannten Antworten sprechen.

  1. Herauszufinden, welcher Teil der oben Migration gearbeitet. Kommentar diejenigen aus.
  2. Auch auf Kommentar / den Teil der Migration entfernen, die brachen.
  3. Führen Sie die Migration erneut. Nun wird es die nicht-gebrochene Teile der Migration abgeschlossen haben, die Teile übersprungen, die bereits geschehen ist.
  4. Kommentar- die Bits der Migration Sie in Schritt 1 Kommentar gesetzt.

können Sie wandern nach unten und wieder nach oben, wenn Sie überprüfen möchten, dass Sie es jetzt haben.

Ich bin damit einverstanden, dass Sie PostgreSQL, wenn möglich verwenden sollten. Wenn Sie jedoch mit MySQL stecken geblieben sind, können Sie die meisten dieser Probleme vermeiden, indem Sie die Migration auf Ihre Testdatenbank versuchen, zuerst:

rake db:migrate RAILS_ENV=test

Sie können zum vorherigen Zustand zurück und versuchen Sie es erneut mit

rake db:schema:load RAILS_ENV=test

2015 mit Rails 4.2.1 und MySQL 5.7, eine gescheiterten Migration kann nicht mit Standard-Rake Aktionen festgelegt werden, die Schienen bieten, wie es im Jahr 2009 war.

MySql nicht Rollback von DDL statments unterstützen (unter MySQL 5.7 Handbuch ). Und Rails können nicht mit, dass alles tun.

Außerdem können wir überprüfen, wie Rails die Arbeit tut: Eine Migration ist in einer Transaktion eingewickelt je nachdem, wie Verbindungsadapter reagiert auf :supports_ddl_transactions?. Nach einer Suche nach dieser Aktion an der Quelle (v 4.2.1) Scheine ich, dass nur gefunden Sqlite3 und Standard es wird nicht unterstützt.

Bearbeiten So ist die aktuelle Antwort auf die ursprüngliche Frage. Eine nicht bestandene MySQL Migration manuell festgelegt werden muss,

Der einfache Weg, dies zu tun ist, um alle Ihre Aktionen in einer Transaktion wickeln:

class WhateverMigration < ActiveRecord::Migration

 def self.up
    ActiveRecord::Base.transaction do
...
    end
  end

  def self.down
    ActiveRecord::Base.transaction do
...
    end
  end

end

Als Luke Francl stellte fest: „MySql [ 's MyISAM-Tabellen nicht] unterstützen Transaktionen.“ - weshalb man bedenkt, könnte MySQL im Allgemeinen zu vermeiden oder zumindest MyISAM insbesondere

Wenn Sie mit InnoDB MySQL, dann wird die oben gut funktionieren. Alle Fehler in entweder nach oben oder unten wieder aus.

beachten einige Arten von Aktionen können nicht über Transaktionen rückgängig gemacht werden. Im Allgemeinen Tabellenänderungen (eine Tabelle löschen, zu entfernen oder Hinzufügen von Spalten, etc.) können nicht rückgängig gemacht werden.

Führen Sie einfach die unten Migration von der Konsole aus:

http: //gilesbowkett.blogspot .com / 2007/07 / how-to-use-Migrationen-from-console.html (klicken Sie auf seine pastie durch)

Ich hatte einen Tippfehler (in "add_column"):

  

def self.up

add_column :medias, :title, :text
add_colunm :medias, :enctype, :text
     

Ende

     

def self.down

remove_column :medias, :title
remove_column :medias, :enctype   
     

Ende

und dann Ihr Problem (kann nicht teilweise fehlgeschlagenen Migration rückgängig machen). nachdem einige googeln gescheitert lief ich dies:

  

def self.up

remove_column :medias, :title
add_column :medias, :title, :text
add_column :medias, :enctype, :text
     

Ende

     

def self.down

remove_column :medias, :title
remove_column :medias, :enctype
     

Ende

, wie Sie habe ich nur noch die Korrekturlinie mit der Hand sehen, und dann wieder entfernt, bevor ich es eincheckten.

Alejandro Babio Antwort über die beste aktuelle Antwort.

Ein zusätzliches Detail, das ich hinzufügen möchten:

Wenn die myfailedmigration Migration fehlschlägt, wird es nicht so angewandt betrachtet, und dies kann durch Ausführen rake db:migrate:status überprüft werden, was eine Ausgabe ähnlich den folgenden zeigen würde:

$  rake db:migrate:status
database: sample_app_dev

 Status   Migration ID    Migration Name
--------------------------------------------------
   up      20130206203115  Create users
   ...
   ...
   down    20150501173156  Test migration

Die Restwirkung add_column :assets, :test, :integer auf der ausgefallene Migration ausgeführt wird, wird auf Datenbankebene mit einer alter table assets drop column test; Abfrage umgekehrt werden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top