単一の移行ファイルを実行する


267

単一の移行を実行する簡単な方法はありますか?特定のバージョンに移行したくありません。特定のバージョンを実行したいだけです。


これは、たまたま必要だったためにマイグレーションとして一度実行したものであり、その後、何度も実行する必要がある可能性のある有用なクエリであることが判明しましたか?おそらく、マイグレーションの内容をモデルまたは他のオブジェクトにリファクタリングし、マイグレーションがその新しい場所を参照するようにする必要があります。その後、コマンドラインでrubyを呼び出すことで、自由に新しいオブジェクトを実行できます。
Nathan Feger、

回答:


240

rubyファイルから直接コードを実行できます。

rails console
>> require "db/migrate/20090408054532_add_foos.rb"
>> AddFoos.up

注:新しいバージョンのレールでは、AddFoos.new.upではなくが必要になる場合がありAddFoos.upます。

requireがクラス名の配列を返すという事実に依存する別の方法(IRBなし):

script/runner 'require("db/migrate/20090408054532_add_foos.rb").first.constantize.up'

これを行うと、おそらくschema_migrationsテーブルは更新されませんが、とにかくそれが望ましいようです。


59
場合によっては、requireパスの前に「./」が必要ですが、schema_migrationsは確実に更新されません。
Beardo

14
呼び出す前に、移行オブジェクトのインスタンスを作成する必要がありました。例AddFoos.new.up
Bentleyo 2012年

15
だから、Railsの3.2のために要約する:require "./db/migrate/db/migrate/20090408054532_add_foos.rb"その後AddFoos.new.up
trisweb

50
移行changeupandの代わりにを使用するdown場合は、実行する必要がありますAddFoos.new.migrate(:up)
Don Werve 2013年

6
レール4では、電話をかけることができますAddFoos.new.change
lfender6445 2013

429

Railsのかなり最近のバージョンを想定すると、いつでも実行できます:

rake db:migrate:up VERSION=20090408054532

ここで、versionは移行のファイル名のタイムスタンプです。

編集:過去8年間のある時点で(どのバージョンかわからない)すでに実行されている場合、Railsはこれを実行しないようにするチェックを追加しました。これは、schema_migrations表のエントリで示されています。再実行するには、rake db:migrate:redo VERSION=20090408054532代わりに単に実行します。


124
実際には、コマンドはrake db:migrate:redo VERSION = my_version
Chirag Patel

2
@Chirag Patel:それがまさに私が探していたものです!ありがとう!
Abel

23
redoは、指定された移行のダウン方式とその後のアップ方式を実行します。upはupメソッドのみを実行します。これは、質問者がまさに望んでいることだと思います。
Sven Koschnicke

7
たとえば、データベーススキーマのバージョンが問題の移行よりも新しい場合、「アップ」は実行されないようです。たとえば、他の人の変更をマージするときに発生する可能性があります。
Matt Connolly

3
おかげで、私はとダウンのためにこれを使用rake db:migrate:down VERSION=XXX
Nitrodist

107

特定の移行実行したい場合は、

$ rake db:migrate:up VERSION=20080906120000

マイグレーションを複数回実行したい場合は、

# use the STEP parameter if you need to go more than one version back
$ rake db:migrate:redo STEP=3

単一の移行を複数回実行したい場合は、

# this is super useful
$ rake db:migrate:redo VERSION=20080906120000

(バージョン番号は、移行のファイル名で確認できます)


編集:移行ファイルの名前を変更することもできます。例:

20151013131830_my_migration.rb -> 20151013131831_my_migration.rb

次に、通常どおりに移行します。これにより、移行が新しいものとして処理されます(ステージングなどのリモート環境で制御が制限される場合に役立ちます)。

編集2:データベースの移行エントリをnukeすることもできます。例えば:

rails_c> q = "delete from schema_migrations where version = '20151013131830'"
rails_c> ActiveRecord::Base.connection.execute(q)

rake db:migrate次にup、nukedマイグレーションのメソッドを再実行します。


「up」と「redo」はどちらも機能しませんでしたが、schema_migrationsの行の削除は完璧でした。
セソイド

27

次のchangeようなメソッドを実装した場合:

class AddPartNumberToProducts < ActiveRecord::Migration
  def change
    add_column :products, :part_number, :string
  end
end

次のように、移行のインスタンスを作成して実行するmigrate(:up)migrate(:down)、インスタンス上で実行できます。

$ rails console
>> require "db/migrate/20090408054532_add_part_number_to_products.rb"
>> AddPartNumberToProducts.new.migrate(:down)

1
これは、upおよびを使用している場合にも適用されますdown
2013

17

これは、この移行ファイル「20150927161307_create_users.rb」を再度実行する手順です。

  1. コンソールモードを実行します。(レールc)
  2. そのファイルにあるクラスをコピーしてコンソールに貼り付けます。

    class CreateUsers < ActiveRecord::Migration
      def change
        create_table :users do |t|
          t.string :name
          t.string :email
          t.timestamps null: false   end
        end
      end
    end
  3. クラスのインスタンスを作成しますCreateUsersc1 = CreateUsers.new

  4. changeそのインスタンスのメソッドを実行します。c1.change

たとえば、コンソールで、クラスを含むファイルを必要とするだけですrequire "./db/migrate/20150927161307_create_users.rb"。コピーと貼り付けの代わりに。その後、クラスで定義されたメソッドをインスタンス化して呼び出すことで、同じ方法でクラスを実行できますCreateUsers.new.change
VinnyQ77

13

現在の代わりにrails 5使用することもできますrailsrake

Rails 3-4

# < rails-5.0
rake db:migrate:up VERSION=20160920130051

Rails 5

# >= rails-5.0
rake db:migrate:up VERSION=20160920130051

# or

rails db:migrate:up VERSION=20160920130051

1
また、必要なものも推測しますrails db:migrate VERSION=20160920130051
frenesim、2016年


6

方法1:

rake db:migrate:up VERSION=20080906120000

方法2:

Railsコンソールで1.コンソールに移行クラスをコピーして貼り付けます(たとえば、add_name_to_user.rb)。次に、コンソールで次のように入力します。

Sharding.run_on_all_shards{AddNameToUser.up}

されております!!


5

の代わりにscript/runnerrails runner新しいRails環境で使用する必要がある場合があることに注意してください。


3

コンソールから実行したい場合、これはあなたが探しているものです:

$ rails console
irb(main)> require "#{Rails.root.to_s}/db/migrate/XXXXX_my_migration.rb"
irb(main)> AddFoo.migrate(:up)

私は他の答えを試しましたが、Rails.root私にとっては効果がありませんでした。

また、.migrate(:up)partは、移行が既に実行されているかどうかに関係なく、移行を強制的に再実行します。これは、すでに移行を実行していて、dbをいじって元に戻し、迅速な解決策を取り戻したい場合に便利です。


1

少なくとも最新のRailsリリース(執筆時点では5.2)では、実行中の移行をフィルタリングする方法がもう1つあるようです。SCOPE移行ファイルの選択に使用される環境変数にフィルターを渡すことができます。

2つの移行ファイルが1_add_foos.rbあり、2_add_foos.run_this_one.rb実行していると仮定します

SCOPE=run_this_one rails db:migrate:up

のみを選択して実行します2_add_foos.run_this_one.rb。スコープに一致するすべての移行ファイルが実行されることに注意してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.