运行一个迁移文件

是否有一种简单的方法来运行单个迁移?我不想迁移到某个版本,我只想运行一个特定的版本。

190507 次浏览

假设你可以运行最新版本的Rails:

rake db:migrate:up VERSION=20090408054532

其中version是迁移文件名中的时间戳。

编辑:在过去8年的某个时候(我不确定是哪个版本),Rails添加了检查,如果它已经运行,则阻止它运行。这是由schema_migrations表中的一个条目指示的。要重新运行它,只需执行rake db:migrate:redo VERSION=20090408054532即可。

你可以直接从ruby文件中运行代码:

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

注意:非常老版本的rails可能需要AddFoos.up而不是AddFoos.new.up

另一种方法(没有IRB)依赖于require返回类名数组的事实:

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

注意,如果你这样做,它不会更新schema_migrations表,但这似乎是你想要的。

此外,如果它找不到文件,你可能需要使用require("./db/..."或根据你的工作目录尝试require_relative

请注意,在新的rails环境中,你可能不得不使用rails runner而不是script/runner

如果你想运行特定的迁移,就这样做

$ 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

(您可以在迁移的文件名中找到版本号)


你也可以简单地重命名你的迁移文件,例如:

__abc0 -> __abc1

然后正常迁移,这将把迁移视为一个新的迁移(如果您想在您控制较少的远程环境(如登台)上迁移,则非常有用)。

编辑2:你也可以在数据库中销毁迁移条目。例如:

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

然后,rake db:migrate将重新运行核迁移的up方法。

如果你已经像这样实现了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)

如果你在路径上有问题,你可以使用

require Rails.root + 'db/migrate/20090408054532_add_foos.rb'

方法一:

rake db:migrate:up VERSION=20080906120000

方法2:

在Rails控制台中 1. 在控制台复制粘贴迁移类(例如add_name_to_user.rb) 2. 然后在控制台,键入以下

Sharding.run_on_all_shards{AddNameToUser.up}

结束了!!

这是再次运行迁移文件“20150927161307_create_users.rb”的步骤

  1. 运行控制台模式。(rails 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. Create an instance of the class CreateUsers: c1 = CreateUsers.new

  4. Execute the method change of that instance: c1.change

对于rails 5,你也可以使用rails来代替rake

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

看起来至少在最新的Rails发行版(撰写本文时为5.2)中还有一种过滤正在运行的迁移的方法。可以在SCOPE环境变量中传递一个过滤器,然后使用它来选择迁移文件。

假设有两个迁移文件1_add_foos.rb2_add_foos.run_this_one.rb正在运行

SCOPE=run_this_one rails db:migrate:up

将只选择并运行2_add_foos.run_this_one.rb。请记住,将运行与范围匹配的所有迁移文件。

如果你想从控制台运行它,这是你要找的:

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

我尝试了其他答案,但要求没有Rails.root没有为我工作。

此外,.migrate(:up)部分强制迁移重新运行,无论它是否已经运行。这对于当你已经运行了一个迁移,但因为打乱了db而有点取消了它,并且想要一个快速的解决方案重新启动它的时候很有用。