【问题标题】:rake db:migrate doesn't detect new migration?rake db:migrate 没有检测到新的迁移?
【发布时间】:2010-09-09 09:03:50
【问题描述】:

熟悉 Rails / ActiveRecord 2.1.1

  • 您使用(例如)ruby 脚本创建第一个版本\生成脚手架产品标题:字符串描述:文本 image_url:字符串
  • 这会创建(例如)一个名为 20080910122415_create_products.rb 的迁移文件
  • 您使用 rake db:migrate 应用迁移
  • 现在,您使用 ruby​​ 脚本向产品表中添加一个字段\generate migration add_price_to_product price:decimal
  • 这将创建一个名为 20080910125745_add_price_to_product.rb 的迁移文件
  • 如果您尝试运行 rake db:migrate,它实际上会恢复第一次迁移,而不是应用下一次!所以你的产品表会被破坏!
  • 但是,如果您单独运行 rake,它会告诉您有一个迁移待定

请注意,应用 rake db:migrate(一旦表被销毁)将按顺序应用所有迁移。

我发现的唯一解决方法是指定新迁移的版本,如下所示:

rake db:migrate version=20080910125745

所以我想知道:这是一种预期的新行为吗?

【问题讨论】:

    标签: ruby-on-rails activerecord migration


    【解决方案1】:

    你应该可以使用

    rake db:migrate:up 
    

    强制它继续前进,但你可能会错过团队中其他人的交错迁移

    如果你运行

    rake db:migrate 
    

    两次,它将重新应用您的所有迁移。

    我在使用 SQLite 的 Windows 上遇到了相同的行为,这可能是特定于这种环境的错误。

    编辑 -- 我找到了原因。在 railstie database.rake 任务中,您有以下代码:

    desc "Migrate the database through scripts in db/migrate. Target specific version with VERSION=x. Turn off output with VERBOSE=false."
    task :migrate => :environment do
      ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true
      ActiveRecord::Migrator.migrate("db/migrate/", ENV["VERSION"] ? ENV["VERSION"].to_i : nil)
      Rake::Task["db:schema:dump"].invoke if ActiveRecord::Base.schema_format == :ruby
    end
    

    然后在我的环境变量中我有

    echo %Version% #=> V3.5.0f
    

    在红宝石中

    ENV["VERSION"] # => V3.5.0f
    ENV["VERSION"].to_i #=>0 not nil !
    

    因此 rake 任务调用

    ActiveRecord::Migrator.migrate("db/migrate/", 0)
    

    在 ActiveRecord::Migrator 中我们有:

    class Migrator#:nodoc:
      class << self
        def migrate(migrations_path, target_version = nil)
          case
            when target_version.nil?              then up(migrations_path, target_version)
            when current_version > target_version then down(migrations_path, target_version)
            else                                       up(migrations_path, target_version)
          end
        end
    

    是的,rake db:migrate VERSION=0rake db:migrate:down 的加长版

    编辑 - 我会去更新灯塔错误,但我的超级公司代理禁止我在那里连接

    与此同时,您可以在调用 migrate 之前尝试取消设置 Version ...

    【讨论】:

      【解决方案2】:

      这不是预期的行为。我本来建议将此报告为灯塔上的错误,但我看到你已经already done so!如果您提供更多信息(包括操作系统/数据库/ruby 版本),我会看一下。

      【讨论】:

        【解决方案3】:

        我非常不同意汤姆!这一个错误! V3.5.0f 不是 rake 迁移的有效版本。 Rake 不应该仅仅因为 ruby​​ 选择考虑 "V3.5.0f".to_i 是 0 就使用它来迁移:down ...

        Rake 应该大声抱怨 VERSION 无效,以便用户知道发生了什么 (在你我之间,通过转换为整数来检查版本是否为 YYYYMMDD 格式的时间戳有点轻)

        [该死的 IE6 不允许我发表评论!不,我不能更换浏览器感谢公司]

        【讨论】:

        • 这不是答案,是评论
        【解决方案4】:

        让,

        非常感谢您的调查。你是对的,实际上我认为你发现了一个更严重的错误,即物种“设计错误”。

        发生的事情是 rake 将获取您传递给命令行的任何值并将它们存储为环境变量。最终将被调用的 rake 任务只会从环境变量中提取这些值。 当 db:migrate 查询 ENV["VERSION"] 时,它实际上请求您设置调用 rake 的版本参数。当您调用 rake db:migrate 时,您不会传递任何版本。

        但我们确实有一个名为 VERSION 的环境变量,它已被其他程序设置用于其他目的(我还不知道是哪一个)。而 rake 背后的人(或 database.rake 背后的人)并没有想到会发生这种情况。这是一个设计错误。至少,他们可以使用更具体的变量名称,例如“RAKE_VERSION”或“RAKE_PARAM_VERSION”,而不仅仅是“VERSION”。

        Tom,我绝对不会关闭,而是编辑我关于灯塔的错误报告以反映这些新发现。

        再次感谢 Jean 的帮助。我已经 5 天前在灯塔上发布了这个错误,但仍然没有答案!

        罗洛

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-02-05
          • 2017-01-07
          • 1970-01-01
          • 2012-02-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-09-17
          相关资源
          最近更新 更多