有没有一种简单的方法来运行一次迁移?我不想迁移到某个版本,我只想运行一个特定的版本。
假设你总是可以运行相当新版本的 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
,具体取决于您的工作目录
AddFoos.new.up
require "./db/migrate/db/migrate/20090408054532_add_foos.rb"
然后 AddFoos.new.up
change
而不是 up
和 down
,则您需要运行 AddFoos.new.migrate(:up)
AddFoos.new.change
如果您想run a specific migration,请执行
$ rake db:migrate:up VERSION=20080906120000
如果您想运行迁移 multiple times,请执行
# 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:您也可以只核对数据库中的迁移条目。例如:
rails_c> q = "delete from schema_migrations where version = '20151013131830'"
rails_c> ActiveRecord::Base.connection.execute(q)
rake db:migrate
然后将重新运行 nuked 迁移的 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)
up
和 down
,这也适用。
这是再次运行此迁移文件“20150927161307_create_users.rb”的步骤
运行控制台模式。 (rails c)将该文件中的类复制并粘贴到控制台。类 CreateUsers < ActiveRecord::Migration def change create_table :users do |t| t.string :name t.string :email t.timestamps null: false end end end end 创建类 CreateUsers 的实例:c1 = CreateUsers.new 执行该实例的方法更改:c1.change
require "./db/migrate/20150927161307_create_users.rb"
而不是复制 &粘贴。然后,您可以通过实例化和调用类 CreateUsers.new.change
中定义的方法来以相同的方式运行该类。
从 rails 5
开始,您还可以使用 rails
而不是 rake
导轨 3 - 4
# < rails-5.0
rake db:migrate:up VERSION=20160920130051
导轨 5
# >= rails-5.0
rake db:migrate:up VERSION=20160920130051
# or
rails db:migrate:up VERSION=20160920130051
rails db:migrate VERSION=20160920130051
猜测您需要什么
如果您在使用路径时遇到问题,可以使用
require Rails.root + 'db/migrate/20090408054532_add_foos.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)
部分强制迁移重新运行,无论它是否已经运行。当您已经运行迁移时,这很有用,通过弄乱数据库并想要一个快速的解决方案来重新启动它。
方法一:
rake db:migrate:up VERSION=20080906120000
方法二:
在 Rails 控制台中 1. 在控制台中复制粘贴迁移类(比如 add_name_to_user.rb) 2. 然后在控制台中,键入以下内容
Sharding.run_on_all_shards{AddNameToUser.up}
完成了!!
请注意,您可能必须在新的 Rails 环境中使用 rails runner
而不是 script/runner
。
看起来至少在最新的 Rails 版本(撰写本文时为 5.2)中,还有另一种过滤正在运行的迁移的方法。可以在 SCOPE
环境变量中传递过滤器,然后使用该过滤器选择迁移文件。
假设您有两个迁移文件 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
。请记住,将运行与范围匹配的所有迁移文件。
rake db:migrate:down VERSION=XXX
上