只进行一次迁移
Posted
技术标签:
【中文标题】只进行一次迁移【英文标题】:Rake just one migration 【发布时间】:2010-11-22 19:33:00 【问题描述】:我试图在我的 rails 应用程序中只运行一个迁移。我怎样才能做到这一点?我不想在它之前或之后运行任何迁移。谢谢。
【问题讨论】:
这将是一个方便的 rails 功能:将STEP=n
参数添加到 db:migrate
(其中 n
是要运行的迁移数,就像 db:rollback
一样) - 然后你可以做rake db:migrate STEP=1
或rake db:migrate STEP=2
等。
【参考方案1】:
rake db:migrate:up VERSION=version_no
将迁移(添加)特定的迁移脚本
rake db:migrate:down VERSION=version_no
将删除特定的迁移脚本
【讨论】:
【参考方案2】:当我对迁移进行大量更改时,我会在开发中使用这种技术,并且我不想大量迁移并在此过程中丢失任何数据(尤其是当我导入需要花费大量时间的遗留数据时)很长一段时间,我不想再次重新导入)。
这是 100% hackish,我绝对不建议在生产中这样做,但它会成功:
-
将要重新运行的迁移从其目录移到临时位置
生成另一个同名迁移
将原始迁移代码复制/粘贴到新生成的迁移文件中
运行新的迁移
删除新生成的迁移文件
编辑架构迁移以删除最新值
恢复旧的迁移文件
【讨论】:
【参考方案3】:加上我的 2 美分,因为我遇到了同样的问题:
如果您绝对想再次运行迁移而不创建新迁移,您可以执行以下操作:
rails dbconsole -p
devdb=# delete from public.schema_migrations where version = '20150105181157';
Rails 会“忘记”它为 20150105181157 运行了迁移。现在,当您运行 db:migrate 时,它会再次运行它。
不过,这几乎总是一个坏主意。它可能有意义的一个实例是,如果您有一个开发分支并且您还没有充实您的迁移并希望在开发中添加一些东西。但即便如此,最好还是进行双向迁移,这样您就可以正确回滚并反复重试。
【讨论】:
【参考方案4】:rake db:migrate:redo version='xxxx'
记得在 xxxx 两边加上引号,xxxx 是您迁移的时间戳(或迁移 ID)。
您可以通过使用检查您之前完成的迁移的时间戳(迁移 ID)
rake db:migrate:status
【讨论】:
【参考方案5】:扩展上面 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。
【讨论】:
【参考方案6】:我有一个实用方法可以让开发变得非常容易。我发现它可以帮助我避免创建过多的迁移——通常我会修改迁移直到它们被部署。
http://fullware.net/index.php/2011/05/26/easily-load-rails-migrations-for-console-execution/
【讨论】:
【参考方案7】:我不得不运行一个已更改且需要独立于所有其他迁移重新运行的迁移。启动控制台并执行以下操作:
>> require 'db/migrate/your_migrations.rb'
=> ["YourMigrations"]
>> YourMigrations.up
=> etc... as the migration runs
>> YourMigration.down
更有用的是,这可以放入 rake 任务等中。
【讨论】:
这非常有效。您也可以将迁移中的代码复制粘贴到控制台中以定义类(如果需要,如果您在 Dev 上犯了错误,这允许手动操作)。如果您使用change
定义了一个可逆迁移,请改为运行YourMigrations.migrate(:up)
(或:down
!)
你可能需要require "#Rails.root/db/migrate/your_migrations.rb"
【参考方案8】:
rake db:migrate:up VERSION=1234567890
类似地rake db:migrate:down
来取消特定的迁移。您可以通过rake -T
获取可用的 rake 任务列表。
【讨论】:
这里提到的VERSION
是每个迁移文件开头的整数值(这只是它创建时的时间戳)。例如,VERSION=20150720023630
。
使用 rake db:migrate:status 可以很好地显示版本
值得注意的是,VERSION
只是一个环境变量,因此它可以在命令中出现,甚至可以设置在命令之前:VERSION=1234567890 rake db:migrate:up
【参考方案9】:
rake db:migrate:redo VERSION=xxxxxxx
,但这将运行down
,然后是up
步骤。您可以结合临时注释掉向下步骤来执行此操作。
【讨论】:
嗯,blog.stonean.com/2007/12/18/rake-dbmigrateredo,::redo 似乎没有接受 VERSION 参数。 @pedrorolo:这并不过时。此任务没有描述,因此不会显示在rake -T
。
@pedrorolo: db:test:prepare
也没有出现在该列表中。上帝啊,我迟到了。
为了扩展 Ryan 所说的,如果表已从 Rails 之外的数据库中删除,rake db:migrate:up VERSION=my_version
可能什么都不做,因为 schema_migrations 表仍然说它是已运行。在同样的情况下,rake db:migrate:redo VERSION=my_version
可能会失败,因为它无法删除表。这种情况下,暂时注释掉迁移中的down
方法,重新运行rake db:migrate:redo...
并扩展@Leo所说的,如果迁移是用def change定义的,那么除了上述之外,将其更改为def self.up。【参考方案10】:
必须有一种方法可以通过控制台运行迁移类。我似乎无法识别迁移代码。
但是,正如 cmets 所示,最好按顺序运行迁移。使用:
rake db:migrate VERSION=##########
在迁移到脚本/控制台时复制并粘贴您的代码?
【讨论】:
【参考方案11】:rake db:migrate VERSION=20098252345
试试看。
【讨论】:
我认为这将运行任何迁移到您指定的迁移。 关闭,但这也会在特定迁移之前运行任何迁移。 我认为您不应该/想要只运行一次迁移而不考虑之前的迁移。迁移是数据库结构的表示,因为它与给定时间点的代码相关,因此之前的迁移是必要的。如果您只想运行 一个 迁移,则很可能您没有编写正确的向上/向下操作来保持迁移的功能......只编写向上迁移是一个坏习惯。 值得注意的是:VERSION
只是一个环境变量,因此它可以在命令中出现,甚至可以设置在命令之前:VERSION=20098252345 rake db:migrate
以上是关于只进行一次迁移的主要内容,如果未能解决你的问题,请参考以下文章