【问题标题】:Run a single migration file运行单个迁移文件
【发布时间】:2010-10-19 17:29:55
【问题描述】:

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

【问题讨论】:

  • 这是您作为迁移运行一次的东西,因为它碰巧需要,然后结果是一个有用的查询,可能需要运行多次?也许您应该将迁移的内容重构为模型或其他对象,然后让迁移引用该新位置。然后,您可以通过在命令行上调用 ruby​​ 来随意执行新对象。

标签: ruby-on-rails ruby migration


【解决方案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】:

请注意,您可能必须在新的 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)
    

    【讨论】:

    • 即使您使用的是updown,这也适用。
    • 帮助我运行迁移 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_shards{AddNameToUser.up}
      

      完成了!!

      【讨论】:

        【解决方案8】:

        这是再次运行此迁移文件“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. 创建类CreateUsers的实例:c1 = CreateUsers.new

        4. 执行该实例的方法changec1.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.rb2_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) 部分强制迁移重新运行,无论它是否已经运行。当您已经运行迁移时,这很有用,通过弄乱数据库并希望快速解决它来恢复它。

          【讨论】:

            猜你喜欢
            • 2023-04-08
            • 2017-09-21
            • 2020-01-07
            • 2020-01-02
            • 2022-01-03
            • 1970-01-01
            • 2022-10-25
            • 2016-08-29
            相关资源
            最近更新 更多