运行单个迁移文件
Posted
技术标签:
【中文标题】运行单个迁移文件【英文标题】:Run a single migration file 【发布时间】:2010-10-19 17:29:55 【问题描述】:是否有一种简单的方法来运行单个迁移?我不想迁移到某个版本,我只想运行一个特定的版本。
【问题讨论】:
这是您作为迁移运行一次的东西,因为它碰巧需要,然后结果是一个有用的查询,可能需要运行多次?也许您应该将迁移的内容重构为模型或其他对象,然后让迁移引用该新位置。然后,您可以通过在命令行上调用 ruby 来随意执行新对象。 【参考方案1】:假设您始终可以运行最新版本的 Rails:
rake db:migrate:up VERSION=20090408054532
其中 version 是迁移文件名中的时间戳。
编辑:在过去 8 年的某个时间点(我不确定是哪个版本)Rails 添加了检查以防止它在已经运行的情况下运行。这由schema_migrations
表中的条目指示。要重新运行它,只需执行rake db:migrate:redo VERSION=20090408054532
。
【讨论】:
其实命令是rake db:migrate:redo VERSION=my_version @Chirag Patel:这正是我想要的!谢谢! redo 运行给定迁移的 down-method 和之后的 up 方法。 up 只运行 up-method,我认为这正是提问者想要的。 如果数据库架构版本晚于相关迁移,'up' 似乎不会运行,例如,在合并其他人的更改时可能会发生这种情况。 谢谢,我把它用在了rake db:migrate:down VERSION=XXX
【参考方案2】:
您可以直接从 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
,具体取决于您的工作目录
【讨论】:
有时你需要在 require 路径前加上一个 './',它肯定不会更新 schema_migrations。 我必须先创建迁移对象的实例,然后才能调用。例如AddFoos.new.up
所以,总结一下 Rails 3.2:require "./db/migrate/db/migrate/20090408054532_add_foos.rb"
然后AddFoos.new.up
如果您的迁移使用change
而不是up
和down
,则需要运行AddFoos.new.migrate(:up)
在rails 4中,你可以调用AddFoos.new.change
【参考方案3】:
请注意,您可能必须在新的 Rails 环境中使用 rails runner
而不是 script/runner
。
【讨论】:
【参考方案4】:如果你想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
方法。
【讨论】:
“up”和“redo”都对我不起作用,但删除 schema_migrations 中的行是完美的。【参考方案5】:如果你实现了这样的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
,这也适用。
帮助我运行迁移 AddPartNumberToProducts.new.migrate(:up) 但奇怪的是这个 AddPartNumberToProducts.up 不起作用【参考方案6】:
如果您在使用路径时遇到问题,可以使用
require Rails.root + 'db/migrate/20090408054532_add_foos.rb'
【讨论】:
【参考方案7】:方法一:
rake db:migrate:up VERSION=20080906120000
方法二:
在 Rails 控制台中 1. 在控制台中复制粘贴迁移类(比如 add_name_to_user.rb) 2. 然后在控制台中输入以下内容
Sharding.run_on_all_shardsAddNameToUser.up
完成了!!
【讨论】:
【参考方案8】:这是再次运行此迁移文件“20150927161307_create_users.rb”的步骤
-
运行控制台模式。 (轨道 c)
将该文件中的类复制并粘贴到控制台。
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
创建类CreateUsers
的实例:c1 = CreateUsers.new
change
:c1.change
【讨论】:
只需要带有类的文件,例如在控制台中:require "./db/migrate/20150927161307_create_users.rb"
而不是复制和粘贴。然后,您可以通过实例化和调用类CreateUsers.new.change
中定义的方法以相同的方式运行该类。
完美!谢谢【参考方案9】:
从rails 5
开始,您还可以使用rails
代替rake
轨道 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 db:migrate VERSION=20160920130051
【参考方案10】:
看起来至少在最新的 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
。请记住,将运行与范围匹配的所有迁移文件。
【讨论】:
【参考方案11】:如果你想从控制台运行它,这就是你要找的:
$ rails console
irb(main)> require "#Rails.root.to_s/db/migrate/XXXXX_my_migration.rb"
irb(main)> AddFoo.migrate(:up)
我尝试了其他答案,但要求没有Rails.root
对我不起作用。
另外,.migrate(:up)
部分强制迁移重新运行,无论它是否已经运行。当您已经运行迁移时,这很有用,通过弄乱数据库并希望快速解决它来恢复它。
【讨论】:
以上是关于运行单个迁移文件的主要内容,如果未能解决你的问题,请参考以下文章