为什么' rake db:rollback'回滚2步而不是默认值1

时间:2015-03-10 20:20:30

标签: ruby-on-rails ruby ruby-on-rails-4 rake

我遇到rake db:rollback的问题。这是设置:

一周前,我从存储库中提取了一些更改,其中包括新的迁移。我跑了rake db:migrate,一切都很好。快进7天(以及多次提交和推送),我开始研究新功能。我创建了一个新的功能分支,然后创建了一个新的迁移。我运行了迁移,编写了一些代码,然后意识到我在刚刚创建的迁移中犯了一个小错误。我以为我可以运行rake db:rollback,对该迁移进行一些更改,然后再次rake db:migrate

但这就是问题所在。当我运行rake db:rollback时,它会回滚两次迁移而不是一次。运行rake db:migrate然后迁移这两个迁移。我可以整天来回走动,但每次它总是回滚2次迁移。

我在stackoverflow上做了一些搜索,发现this question专门引用了可以添加到migraterollback的STEP参数,但是经历了该问题中的所有内容没帮我最初我运行echo $STEP时没有返回任何内容,所以我专门用export STEP=1设置了它,但这并没有帮助:rake db:rollback每次仍然回滚2步。而且,即使我运行rake db:rollback STEP=1,它仍然会回滚两步。

另外,我检查了架构中的版本号,在运行rake db:migrate之后,版本与我刚刚创建的最新迁移一致。运行rake db:rollback并返回2个步骤后,版本号与最近的第2次迁移一致。

我想解决这个问题有两个原因:

  1. 我只需要回滚一次迁移,这样我就可以提交更改,然后切换回开发分支,而不会污染开发架构。
  2. 我想完全理解rake db:rollback的工作原理。也许有办法解决这个问题并让事情继续下去,但我希望在更深层次上理解这一点。
  3. 是否有某种应用程序配置可以确定这一点?有一些电线交叉,我需要手动重置一些东西?谢谢你的帮助!

    更新

    根据一些意见和回应:

    我在.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行?公寓宝石会导致第二步回滚吗?

2 个答案:

答案 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