只需进行一次迁移


94

我正在尝试在我的Rails应用程序中进行全部迁移中的一个。我怎样才能做到这一点?我不想在迁移之前或之后进行任何迁移。谢谢。


1
这将是一个方便的rails功能:STEP=ndb:migrate(添加n要运行的迁移的数量在哪里,就像在for上一样db:rollback)添加一个参数-然后就可以执行rake db:migrate STEP=1or rake db:migrate STEP=2等等
。– user664833

Answers:


164

rake db:migrate:redo VERSION=xxxxxxx,但这将运行down然后执行该up步骤。您可以结合注释掉向下的步骤来执行此操作。


嗯,blog.stonean.com/2007/12/18/rake-dbmigrateredo,:: redo似乎没有VERSION参数。
Terry G Lorber

3
@pedrorolo:这不是过时的。该任务没有描述,因此不会显示在中rake -T
瑞安·比格

1
@pedrorolo:db:test:prepare也不会出现在该列表中。天哪,我迟到了。
mraaroncruz

9
为了扩展Ryan所说的内容,如果该表已从Rails之外的数据库中删除,则rake db:migrate:up VERSION=my_version可能什么也不做,因为schema_migrations表仍然说它已经运行了。在相同的情况下rake db:migrate:redo VERSION=my_version可能会失败,因为它无法删除表。在这种情况下,请down暂时注释掉迁移中的方法,然后重新运行rake db:migrate:redo...
Leo

3
并扩展@Leo所说的内容,如果迁移是通过def change定义的,则除了上述内容外,还应将其更改为defself.up。
2014年

70
rake db:migrate:up VERSION=1234567890

类似地rake db:migrate:down减少特定的迁移。您可以使用来获得可用的瑞克任务列表rake -T


4
这里VERSION提到的是每个迁移文件开头的整数值(这只是创建时间的时间戳)。例如, VERSION=20150720023630
aaron编码

3
该版本与rake db:migrate:status一起很好地显示
jpgeek '17

值得注意的是,VERSION它只是一个环境变量,因此它可以在命令中排在首位,甚至可以在命令前设置:VERSION=1234567890 rake db:migrate:up
Joshua Pinter

25

我必须运行一个已更改的迁移,并且需要独立于所有其他迁移来重新运行。启动控制台并执行以下操作:

>> require 'db/migrate/your_migrations.rb'
=> ["YourMigrations"]
>> YourMigrations.up
=> etc... as the migration runs
>> YourMigration.down

更有用的是,可以将其放入rake任务等中。


6
这很棒。您也可以只将代码从迁移中复制粘贴到控制台中以定义类(例如,如果您在Dev上犯了错误,则可以根据需要进行手动操作)。如果您使用定义了可逆迁移change,请YourMigrations.migrate(:up)改为(或:down也可以运行)
trisweb 2013年

1
您可能需要require "#{Rails.root}/db/migrate/your_migrations.rb"
s2t2

15

rake db:migrate:up VERSION=version_no

将迁移(添加)特定的迁移脚本

rake db:migrate:down VERSION=version_no

将删除特定的迁移脚本


10
rake db:migrate VERSION=20098252345

试试看。


7
我认为这将进行所有迁移,直到您指定的迁移为止。
刘坚

1
关闭,但也可以在特定迁移之前运行所有迁移。
匿名2009年

6
我认为您不应该/只想运行一个迁移而无需考虑之前的迁移。迁移是数据库结构的表示形式,因为它与给定时间点的代码相关,因此迁移是必需的。如果您只想运行一个迁移,则可能是您没有编写适当的上/下操作来保持迁移功能……仅写上一个迁移是一个坏习惯。
JP Silvashy 09年

1
值得注意的是:VERSION只是一个环境变量,因此它可以在命令中排在首位,甚至可以在命令前设置:VERSION=20098252345 rake db:migrate
Joshua Pinter

4
rake db:migrate:redo version='xxxx'   

请记住,在xxxx前后加上引号,xxxx是迁移的时间戳(或迁移ID)。

您可以使用来检查之前完成的迁移的时间戳(迁移ID)

rake db:migrate:status    

3

通过上面的korch扩展答案,require对我load没有用,但是有帮助。具体来说,对于迁移文件:

    class ChangeMinQuantityToRaces < ActiveRecord::Migration
      def change
        change_column :races, :min_quantity, :integer, :default => 0
      end
    end

在控制台中键入

    > load 'db/migrate/30130925110821_change_min_quantity_to_races.rb'
    > ChangeMinQuantityToRaces.new.change

为我工作。

    > Race.new.min_quantity # => 0 

这用于ruby 1.9.3p484(2013-11-22修订版43786)[x86_64-linux]和Rails 3.2.13。


2

加上2美分是因为遇到了同一问题:

如果您绝对要在不创建新迁移的情况下再次进行迁移,则可以执行以下操作:

rails dbconsole -p devdb=# delete from public.schema_migrations where version = '20150105181157';

Rails会“忘记”它已为20150105181157运行了迁移。现在,当您运行db:migrate时,它将再次运行它。

但是,这几乎总是一个坏主意。可能有意义的一个例子是,如果您有一个开发分支,但还没有充实您的迁移,并想在开发中添加一些东西。但是即使那样,最好还是进行两次迁移,以便您可以正确地回滚并重复尝试。


1

必须有一种通过控制台运行迁移类的方法。我似乎无法识别迁移代码。

但是,正如注释所示,最好按顺序运行迁移。用:

rake db:migrate VERSION=##########

将代码复制并粘贴到迁移到脚本/控制台的迁移中?



0

当我大量更改迁移时,我不想在迁移中丢失大量数据(尤其是当我导入需要很长时间才能导入的旧数据时)时,就在开发中使用了此技术。我不想再次重新导入)。

这是100%的骇客行为,我绝对不建议在生产中这样做,但可以做到这一点:

  1. 将要重新运行的迁移从其目录移至临时位置
  2. 生成另一个同名迁移
  3. 将原始迁移代码复制/粘贴到新生成的迁移文件中
  4. 运行新的迁移
  5. 删除新生成的迁移文件
  6. 编辑架构迁移以删除最新值
  7. 恢复旧的迁移文件
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.