82

失敗したレール移行をどのようにロールバックしますか? 失敗した移行を元に戻すことができると思いrake db:rollbackますが、いいえ、以前の移行をロールバックします (失敗した移行から 1 を引いた値)。そしてrake db:migrate:down VERSION=myfailedmigration、どちらも機能しません。私はこれに数回遭遇しましたが、非常にイライラしています。問題を再現するために作成した簡単なテストを次に示します。

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

結果:

== SimpleTest: 移行中 ============================================= ========
-- add_column(:assets, :test, :integer)
   -> 0.0932 秒
-- add_column(:asset, :error)
レーキが中止されました!
エラーが発生しました。以降の移行はすべてキャンセルされました:

引数の数が間違っています (3 に対して 2)

わかりました、ロールバックしましょう:

$ rake db:ロールバック
== AddLevelsToRoles: 元に戻す =========================================== ==
-- remove_column(:roles, :level)
   -> 0.0778 秒
== AddLevelsToRoles: 元に戻されました (0.0779s) =====================================

は?これは、失敗した移行ではなく、SimpleTest の前の最後の移行でした。(そして、移行の出力にバージョン番号が含まれていればいいのですが。)

それでは、失敗した移行 SimpleTest のダウンを実行してみましょう。

$ rake db:migrate:down VERSION=20090326173033
$

何も起こらず、出力もありません。しかし、とにかく移行を実行したのでしょうか? それでは、SimpleTest 移行の構文エラーを修正して、もう一度実行してみましょう。

$ rake db:migrate:up VERSION=20090326173033
== SimpleTest: 移行中 ============================================= ========
-- add_column(:assets, :test, :integer)
レーキが中止されました!
Mysql::エラー: 列名 'test' が重複しています: ALTER TABLE `assets` ADD `test` int(11)

いいえ。明らかに、migrate:down は機能しませんでした。失敗しているのではなく、実行していないだけです。

手動でデータベースにアクセスして削除し、テストを実行する以外に、その重複テーブルを取り除く方法はありません。それよりも良い方法があるはずです。

4

9 に答える 9

83

残念ながら、失敗した MySQL の移行は手動でクリーンアップする必要があります。MySQL は、トランザクション データベース定義の変更をサポートしていません。

Rails 2.2 には、PostgreSQL のトランザクション移行が含まれています。Rails 2.3 には、SQLite のトランザクション移行が含まれています。

これは現在の問題にはあまり役に立ちませんが、将来のプロジェクトでデータベースを選択できる場合は、トランザクション DDL をサポートするデータベースを使用することをお勧めします。これにより、移行がはるかに快適になります。

更新 - これは、Rails 4.2.7 および MySQL 5.7 の 2017 年にも当てはまり、別の回答で Alejandro Babio によって報告されています。

于 2009-03-26T18:26:32.687 に答える
20

OK、皆さん、これが実際のやり方です。上記の回答が何について話しているのかわかりません。

  1. アップ マイグレーションのどの部分が機能したかを把握します。それらをコメントアウトします。
  2. また、移行で壊れた部分をコメント アウト/削除します。
  3. 移行を再度実行します。これで、移行の壊れていない部分が完了し、既に完了した部分はスキップされます。
  4. 手順 1 でコメントアウトした移行の一部のコメントを外します。

今すぐ取得したことを確認したい場合は、移行して再度バックアップすることができます。

于 2011-03-29T01:01:15.227 に答える
20

指定したバージョンに移動するには、次を使用します。

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

ただし、移行が途中で失敗した場合は、最初にクリーンアップする必要があります。1つの方法は次のとおりです。

  • 移行の方法を編集して、機能downした部分を元に戻すだけですup
  • 以前の状態 (開始した場所) に戻す
  • 移行を修正します (への変更を元に戻すことを含むdown)
  • 再試行
于 2009-03-26T18:00:38.957 に答える
13

可能な場合は PostgreSQL を使用する必要があることに同意します。ただし、MySQL に行き詰まっている場合は、最初にテスト データベースで移行を試みることで、これらの問題のほとんどを回避できます。

rake db:migrate RAILS_ENV=test

前の状態に戻って再試行できます

rake db:schema:load RAILS_ENV=test
于 2010-12-10T10:09:53.173 に答える
8

これを行う簡単な方法は、すべてのアクションをトランザクションにラップすることです。

class WhateverMigration < ActiveRecord::Migration

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

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

end

Luke Francl が指摘したように、「MySql [の MyISAM テーブルはトランザクションをサポートしていません]」-これが、一般的に MySQL を避けるか、特に MyISAM を避けることを検討する理由です。

MySQL の InnoDB を使用している場合、上記は問題なく動作します。アップまたはダウンのいずれかでエラーが発生すると、取り消されます。

一部のタイプのアクションは、トランザクションを介して元に戻すことができないことに注意してください。通常、テーブルの変更 (テーブルの削除、列の削除または追加など) はロールバックできません。

于 2009-04-01T17:41:30.343 に答える
1

(「add_column」に)タイプミスがありました:

def self.up

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

終わり

def self.down

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

終わり

そしてあなたの問題(部分的に失敗した移行を元に戻すことはできません)。いくつかのグーグルが失敗した後、私はこれを実行しました:

def self.up

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

終わり

def self.down

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

終わり

ご覧のとおり、チェックインする前に、修正ラインを手動で追加してから、再度削除しました。

于 2010-03-02T10:04:42.760 に答える
1

上記の Alejandro Babio の回答は、現在の最良の回答を提供します。

追加したい追加の詳細:

移行が失敗するmyfailedmigrationと、適用済みとは見なされず、これは を実行して確認できますrake db:migrate:status。次のような出力が表示されます。

$  rake db:migrate:status
database: sample_app_dev

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

失敗した移行で実行された残りの影響はadd_column :assets, :test, :integer、クエリを使用してデータベース レベルで元に戻す必要がありalter table assets drop column test;ます。

于 2015-05-01T18:07:02.147 に答える
1

コンソールからダウン マイグレーションのみを実行します。

http://gilesbowkett.blogspot.com/2007/07/how-to-use-migrations-from-console.html (クリックしてパスティを表示)

于 2010-01-24T22:37:05.153 に答える