我遇到rake db:rollback
的问题。这是设置:
一周前,我从存储库中提取了一些更改,其中包括新的迁移。我跑了rake db:migrate
,一切都很好。快进7天(以及多次提交和推送),我开始研究新功能。我创建了一个新的功能分支,然后创建了一个新的迁移。我运行了迁移,编写了一些代码,然后意识到我在刚刚创建的迁移中犯了一个小错误。我以为我可以运行rake db:rollback
,对该迁移进行一些更改,然后再次rake db:migrate
。
但这就是问题所在。当我运行rake db:rollback
时,它会回滚两次迁移而不是一次。运行rake db:migrate
然后迁移这两个迁移。我可以整天来回走动,但每次它总是回滚2次迁移。
我在stackoverflow上做了一些搜索,发现this question专门引用了可以添加到migrate
和rollback
的STEP参数,但是经历了该问题中的所有内容没帮我最初我运行echo $STEP
时没有返回任何内容,所以我专门用export STEP=1
设置了它,但这并没有帮助:rake db:rollback
每次仍然回滚2步。而且,即使我运行rake db:rollback STEP=1
,它仍然会回滚两步。
另外,我检查了架构中的版本号,在运行rake db:migrate
之后,版本与我刚刚创建的最新迁移一致。运行rake db:rollback
并返回2个步骤后,版本号与最近的第2次迁移一致。
我想解决这个问题有两个原因:
rake db:rollback
的工作原理。也许有办法解决这个问题并让事情继续下去,但我希望在更深层次上理解这一点。是否有某种应用程序配置可以确定这一点?有一些电线交叉,我需要手动重置一些东西?谢谢你的帮助!
更新
根据一些意见和回应:
我在.bash_profile中明确设置了export STEP=1
,并没有产生任何影响,它仍然会回滚2步。
我知道要迁移到特定版本,是的,这是一种让我到达特定地点的方法。我可以回滚它强制我的两个步骤,然后通过指定版本向前迁移1步。它有效,但不是应该如何工作,我真的想要深究这一切。
rake db:migrate:status
的输出始终返回此错误:
rake aborted!
ArgumentError: invalid value for Integer(): ""
/Users/eliduke/.rvm/gems/ruby-2.1.0/gems/activerecord-4.0.5/lib/active_record/railties/databases.rake:98:in `%'
/Users/eliduke/.rvm/gems/ruby-2.1.0/gems/activerecord-4.0.5/lib/active_record/railties/databases.rake:98:in `block (4 levels) in <top (required)>'
/Users/eliduke/.rvm/gems/ruby-2.1.0/gems/activerecord-4.0.5/lib/active_record/railties/databases.rake:98:in `map!'
/Users/eliduke/.rvm/gems/ruby-2.1.0/gems/activerecord-4.0.5/lib/active_record/railties/databases.rake:98:in `block (3 levels) in <top (required)>'
/Users/eliduke/.rvm/gems/ruby-2.1.0/bin/ruby_executable_hooks:15:in `eval'
/Users/eliduke/.rvm/gems/ruby-2.1.0/bin/ruby_executable_hooks:15:in `<main>'
Tasks: TOP => db:migrate:status
rake db:version
的输出可能表现得很奇怪。如果我刚刚迁移到最近,它是20150309194758
,这与我最近的迁移相对应。如果我刚刚回滚(这两个步骤迫使我),版本为20150203171351
,这对应于 3 后退的步骤。这是正常的吗?不应该是20150303192838
,这是两步之后吗?
此外,我现在看到rake db:rollback
输出的特殊性。它首先显示正常(1步)的第一次迁移的回滚,然后看起来可能是公寓宝石正在瞄准并回滚下一次迁移(2步)。
== 20150309194758 CreateFeeds: reverting ======================================
-- drop_table(:feeds, {:id=>false})
-> 0.0291s
== 20150309194758 CreateFeeds: reverted (0.0293s) =============================
Rolling back development tenant
== 20150303192838 AddDisplayRankToEventPrizes: reverting ======================
-- remove_column(:event_prizes, :display_rank, :integer, {:index=>true, :after=>:winner_user_id})
-> 0.5963s
== 20150303192838 AddDisplayRankToEventPrizes: reverted (0.5964s) =============
看到Rolling back development tenant
行?公寓宝石会导致第二步回滚吗?
答案 0 :(得分:1)
如果您有特定的迁移,并且不希望触及任何其他迁移,则可以运行rake db:migrate:redo VERSION="XXXXXXXXXXX"
来重新运行该特定迁移。
VERSION ID是所有迁移前缀的较长数字,仅表示创建它的日期/时间。因此,如果我有一个名为20150114194155_add_foo_to_bar
的迁移文件,我的命令将是这样的:
rake db:migrate:redo VERSION="20150114194155"
如果您确实需要将迁移置于“向下”状态,那么这将是一项更多的工作。首先,确保您的目标迁移具有向下操作。然后,只需运行:
rake db:migrate:down VERSION="20150114194155"
这将对该单个迁移执行“向下”操作。
以下是Rails documentation了解详情。
答案 1 :(得分:0)
在rail codebase you can find中: 第125行
desc 'Rolls the schema back to the previous version (specify steps w/ STEP=n).'
task :rollback => [:environment, :load_config] do
step = ENV['STEP'] ? ENV['STEP'].to_i : 1
ActiveRecord::Migrator.rollback(ActiveRecord::Migrator.migrations_paths, step)
db_namespace['_dump'].invoke
end
因此,如果必须在某处设置环境变量。尽管如此,总是指定步骤数是一个好习惯:
rake db:rollback STEP = 1