rake db:migrate没有检测到新的迁移?

时间:2008-09-16 08:22:04

标签: ruby-on-rails activerecord migration

使用Rails / ActiveRecord 2.1.1

  • 您创建第一个版本(例如)ruby脚本\生成脚手架产品标题:字符串描述:text image_url:string
  • 这创建(例如)名为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

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

4 个答案:

答案 0 :(得分: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

在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

是的,rake db:migrate VERSION=0rake db:migrate:down

的长版本

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

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

答案 1 :(得分:1)

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

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

[该死的IE6不允许我发表评论!并且我不能改变浏览器感谢公司]

答案 2 :(得分:0)

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

答案 3 :(得分:0)

- 琼,

非常感谢您的调查。你是对的,实际上我认为你已经发现了一个更严重的物种'设计虫'的虫子。

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

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

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

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

罗洛梅