运行一个迁移文件


267

有一种简单的方法可以运行单个迁移吗?我不想迁移到某个版本,而只想运行一个特定的版本。


您是否因为恰好需要迁移而将它作为迁移一次运行,然后证明它是一个有用的查询,可能需要多次运行?也许您应该将迁移的内容重构为模型或其他对象,然后让迁移引用该新位置。然后,您可以通过在命令行上调用ruby来简单地执行新对象。
内森·费格

Answers:


239

您可以直接在ruby文件中运行代码:

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

注意:较新版本的rails可能需要AddFoos.new.up而不是AddFoos.up

另一种方法(无IRB)依赖于require要求返回一个类名数组的事实:

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

请注意,如果执行此操作,它可能不会更新schema_migrations表,但是无论如何,这似乎是您想要的。


58
有时,您需要在require路径前添加一个'./',并且它绝对不会更新schema_migrations。
Beardo 2011年

14
在调用之前,我必须创建迁移对象的实例。例如AddFoos.new.up
Bentleyo 2012年

15
因此,总结一下Rails 3.2:require "./db/migrate/db/migrate/20090408054532_add_foos.rb"然后AddFoos.new.up
trisweb

50
如果您的迁移使用的change不是updown,则需要运行AddFoos.new.migrate(:up)
Don Werve

6
在rails 4中,您可以致电AddFoos.new.change
lfender6445

429

假设您使用的是Rails的最新版本,则可以始终运行:

rake db:migrate:up VERSION=20090408054532

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

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


124
实际上,命令是rake db:migrate:redo VERSION = my_version
Chirag Patel 2010年

2
@Chirag Patel:那正是我想要的!谢谢!
亚伯2010年

23
重做将运行给定迁移的缩减方法,然后再运行up方法。up只运行up-method,我认为这正是发问人想要的。
Sven Koschnicke

7
如果数据库架构版本晚于所讨论的迁移,则“ up”似乎不会运行,例如,在合并另一个人的更改时可能会发生。
马特·康诺利

3
谢谢,我将此与rake db:migrate:down VERSION=XXX
Nitrodist

107

如果要运行特定的迁移,请执行

$ 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

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


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

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然后将重新运行up裸迁移的方法。


“ up”和“ redo”都不适合我,但是删除schema_migrations中的行是完美的。
cesoid 2016年

27

如果您实现了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)

1
即使您使用up和,这也适用down
gak

17

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

  4. 执行该change实例的方法:c1.change

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

13

截至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

1
它还猜您需要什么rails db:migrate VERSION=20160920130051
frenesim 2016年


6

方法1:

rake db:migrate:up VERSION=20080906120000

方法2:

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

Sharding.run_on_all_shards{AddNameToUser.up}

完成了!!


5

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


3

如果要从控制台运行它,那么您正在寻找的是:

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

我尝试了其他答案,但Rails.root没有要求对我没有帮助。

此外,.migrate(:up)part强制迁移重新运行,无论迁移是否已经运行。当您已经进行了迁移,通过弄乱数据库来撤消它并希望快速解决方案重新建立迁移时,这很有用。


1

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.