为什么rake抛出这个Rails迁移错误?

时间:2008-10-24 16:22:27

标签: ruby-on-rails migration rake

我有两台机器......一台开发机器和一台生产机器。当我第一次将rails应用程序带到生产服务器上时,我没有遇到任何问题。我只是通过运行rake db:schema导入schema.rb:load RAILS_ENV = production。一切都很好。

然后,在我的开发机器上,我进行了一些更改和另一次迁移,然后将新应用程序复制到生产机器上。然后,我尝试通过运行rake db:migrate RAILS_ENV = production来更新数据库。我收到以下错误: “数据库中已经有一个名为'schema_migrations'的对象。”

我在想,你也不开玩笑......你创造了它!我在耙子上跑了一下,似乎耙子认为这是它第一次跑。但是,通过分析我的开发机器和生产机器上的'schema_migrations'表,您可以看到存在一个迁移的差异,即我想要迁移的迁移。

我还试图明确定义版本号,但这也不起作用。

关于如何使我的生产服务器更新的任何想法?

更新

首先我要说的是,我不能只是“放弃”数据库。它是一个生产服务器,其中已有超过10万条记录。如果将来发生类似问题会怎样?是的,我每次发生数据库问题时都会丢弃表格?这次可能会有效,但对于每个数据库问题,它似乎都不是一个实用的长期解决方案。我怀疑我现在遇到的问题对我来说是独一无二的。

  1. 听起来像'schema_info'表和'schema_migrations'表是相同的。在我的设置中,我只有'schema_migrations'。如前所述,生产服务器上的'schema_migrations'表与开发机器之间的差异只是一条记录。也就是说,记录包含我要迁移的更改的版本号。

  2. 从我读过的书“Simply Rails 2”中,它指出当第一次移动到生产服务器时,不应该运行rake db:migrate,而应该运行rake:db:schema:load。 / p>

  3. 如果重要,我正在使用Rails版本2.1。

9 个答案:

答案 0 :(得分:1)

这是一个猜测,我承认:我认为,因为您首先在生产环境中运行db:schema:load而不是db:migrate,您获得了数据库的结构,但没有迁移的数据填充到您的数据库中schema_info表。所以现在,当你在生产环境中运行迁移时,schema_info中没有数据,这就是为什么迁移认为它尚未运行的原因(因为它还没有)。

那说...你说你已经查看了“schema_migrations”表,并且从开发到生产有一个版本的差异......我没有听说过那个表,虽然我是在我的rails版本上落后几个月。也许您可以尝试使用单个“版本”列在生产环境中创建“schema_info”表,并添加一行,其中包含您认为生产环境所在的版本。

答案 1 :(得分:1)

关于您的更新:

  1. 我不明白你的生产schema_migrations和dev版本之间有什么区别。两个表中是否有记录(应该只有1列,“版本”,右)或者在开发DB中是否有一条记录而在生产中是否有零记录?如果生产表中没有记录,则执行以下操作:

    ActiveRecord::Base.connection.execute("INSERT schema_migrations (version) VALUES(#{my version number that production is supposedly on})")

  2. 或者,您可以尝试完全删除schema_migrations表:

    ActiveRecord::Base.connection.execute("DROP TABLE schema_migrations")

    然后,重新运行rake db:migrate RAILS_ENV=production。这将从版本1开始进行迁移,这可能不是你想要的。

  3. 或者,您也可以在生产环境中启动IRB会话,执行“要求”或“加载”(我永远不会记住您想要的迁移文件的哪个,或者是否重要)加载,然后调用MyMigrationClass.up。您需要在此之后手动设置schema_migrations表中的版本号,因为您仍然会遇到问题,但作为快速修复类型的hack,这将起作用。

答案 2 :(得分:1)

如果你得到“数据库中已有一个名为'schema_migrations'的对象。”错误消息然后我怀疑您使用MS SQLServer作为您的数据库? (因为这看起来像MS SQL Server错误消息)

如果是,那么您使用的是哪个ActiveRecord数据库适配器? (您的database.yml文件是什么,您为安装MS SQL Server数据库安装了哪些宝石?)

目前,似乎Rails在生产模式中找不到schema_migrations表,因此尝试创建它,并且此创建失败并显示数据库错误消息。原因可能是schema_migrations表名中的大写/小写字符 - 据我所知,MS SQL Server标识符区分大小写。

答案 3 :(得分:1)

根据生产中使用的系统,我见过以下工作的情况:

rake db:migrate RAILS_ENV=production

但是这个确实有效:

RAILS_ENV=production rake db:migrate

古怪,我知道,但是值得一试,看看它是否有所作为。

答案 4 :(得分:0)

我会删除数据库,再次添加它并运行rake rb:migrate。 Brad是正确的,当您运行架构加载时,它没有在schema_migrations表中放置任何记录。

如果生产服务器上有数据不能丢失,这当然会更复杂。您可以获得rake备份任务(不确定它是否是核心的一部分)然后在生产数据库上运行rake db:backup:write,然后在生产时获得最新的迁移后,运行rake db:备份:读

答案 5 :(得分:0)

schema_info来自旧版本的Rails。 schema_migrations是块上的新手。您应该能够删除schema_info表,因为它将不再使用。您可能希望搜索与此名称更改相关的任何问题。

答案 6 :(得分:0)

rake db:schema:load将从schema.rb加载数据库结构。此文件是数据库结构的当前表示形式。当您拥有需要创建所有表和索引的空模式(数据库)时,可以使用它。它可以节省您运行所有迁移的麻烦。如果您有一个包含数据的现有生产数据库,则不希望运行它。正如其他人所说的那样糟糕!

答案 7 :(得分:0)

我知道这篇文章是在不久前发布的,但我偶然发现它并没有得到真正的回答。随着它出现在谷歌,这里去。

当您执行rake db:schema:dump时(或者当构建脚本为您完成此操作时),它会将迁移表的定义放入schema.rb中。在脚本结束时,进程将尝试再次创建表,但它显然已存在。只需在运行rake:schema:load之前从schema.rb中删除迁移表,就不会出现错误消息。

您需要在迁移表中设置版本号,以便随后运行迁移。因此,了解schema.rb与哪个版本相关,或者删除所有旧迁移(它们在SCM中是否安全?)

非常重要。

答案 8 :(得分:-1)

rake db:migrate RAILS_ENV=production

仅在第一次创建时使用db:schema:load任务,应迁移增量更改。