运行单个迁移文件

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 而不是updown,则需要运行AddFoos.new.migrate(:up) 在rails 4中,你可以调用AddFoos.new.change【参考方案3】:

如果你想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 中的行是完美的。【参考方案4】:

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

【讨论】:

即使您使用的是updown,这也适用。 帮助我运行迁移 AddPartNumberToProducts.new.migrate(:up) 但奇怪的是这个 AddPartNumberToProducts.up 不起作用【参考方案5】:

这是再次运行此迁移文件“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

    执行该实例的方法changec1.change

【讨论】:

只需要带有类的文件,例如在控制台中:require "./db/migrate/20150927161307_create_users.rb" 而不是复制和粘贴。然后,您可以通过实例化和调用类CreateUsers.new.change 中定义的方法以相同的方式运行该类。 完美!谢谢【参考方案6】:

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【参考方案7】:

如果您在使用路径时遇到问题,可以使用

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

【讨论】:

【参考方案8】:

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

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

我尝试了其他答案,但要求没有Rails.root 对我不起作用。

另外,.migrate(:up) 部分强制迁移重新运行,无论它是否已经运行。当您已经运行迁移时,这很有用,通过弄乱数据库并希望快速解决它来恢复它。

【讨论】:

【参考方案9】:

方法一:

rake db:migrate:up VERSION=20080906120000

方法二:

在 Rails 控制台中 1. 在控制台中复制粘贴迁移类(比如 add_name_to_user.rb) 2. 然后在控制台中输入以下内容

Sharding.run_on_all_shardsAddNameToUser.up

完成了!!

【讨论】:

【参考方案10】:

请注意,您可能必须在新的 Rails 环境中使用 rails runner 而不是 script/runner

【讨论】:

【参考方案11】:

看起来至少在最新的 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。请记住,将运行与范围匹配的所有迁移文件。

【讨论】:

以上是关于运行单个迁移文件的主要内容,如果未能解决你的问题,请参考以下文章

ruby 活动记录和迁移单个文件

我可以将单个文件从 CVS 迁移到 SVN 吗?

outlook 2010到outlook 2007的数据迁移(注意单个PST文件限制20G)

laravel 数据迁移实现订单列表

数据库迁移:单个创建脚本与更改集

一个迁移文件中的多个迁移语句