English 中文(简体)
rake数据库:migrate没有检测到新的迁移?
原标题:
  • 时间:2008-09-16 08:22:03
  •  标签:

经验丰富的Rails/ActiveRecord 2.1.1

  • You create a first version with (for example) ruby scriptgenerate scaffold product title:string description:text image_url:string
  • This create (for example) a migration file called 20080910122415_create_products.rb
  • You apply the migration with rake db:migrate
  • Now, you add a field to the product table with ruby scriptgenerate migration add_price_to_product price:decimal
  • This create a migration file called 20080910125745_add_price_to_product.rb
  • If you try to run rake db:migrate, it will actually revert the first migration, not apply the next one! So your product table will get destroyed!
  • But if you ran rake alone, it would have told you that one migration was pending

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

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

rake db:migrate version=20080910125745

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

最佳回答

你应该能够使用

rake db:migrate:up 

迫使它继续进行,但随后您可能会错过团队中其他人的交错迁移

如果你跑步

rake db:migrate 

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

我在使用SQLite的窗口上遇到了同样的行为,这可能是这种环境特有的错误。

编辑--我找到了原因。在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

用Ruby

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

是的,<code>rake db:migrate VERSION=0</code>是<code>的长版本rake db:migrate:down</code>

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

在此期间,您可以尝试在调用migrate之前取消设置版本。。。

问题回答

这不是预期的行为。我本来打算建议将其报告为灯塔上的一个错误,但我看到你已经已经这样做了!如果您提供更多信息(包括OS/database/ruby版本),我会看一看。

我尊敬地不同意汤姆的观点!这个一个bug!!V3.5.0f不是rake迁移的有效版本。Rake不应该使用它来迁移:down只是因为ruby选择考虑“V3.5.0f”.to_i是0。。。

Rake should loudly complain that VERSION is not valid so that users know what is up (between you and me, checking that the version is a YYYYMMDD formated timestamp by converting to integer is a bit light)

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

斜纹棉布

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

What s happening is that rake will grab whatever value you pass to the command line and store them as environment variables. The rake tasks that will eventually get called will just pull this values from the environment variable. When db:migrate queries ENV["VERSION"], it actually requests the version parameter which you set calling rake. When you call rake db:migrate, you don t pass any version.

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

汤姆,我肯定不会关闭,但会编辑我关于灯塔的错误报告,以反映这些新发现。

再次感谢Jean的帮助。我已经在灯塔上发布了这个bug,持续了5天,但仍然没有得到回复!

罗洛牌手表





相关问题
热门标签