4

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

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

我在想自己,你不开玩笑,瑞克……你创造了它!我在 rake 上运行跟踪,似乎 rake 认为这是它第一次运行。但是,通过分析我的开发机器和生产机器上的“schema_migrations”表,您可以看到一个迁移存在差异,即我想要迁移的那个。

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

关于如何使生产服务器保持最新的任何想法?

更新:

让我首先说我不能只是“删除”数据库。这是一个生产服务器,里面已经有超过 10 万条记录。如果以后出现类似的问题怎么办?我是不是每次发生数据库问题时都删除表?这次它可能会奏效,但它似乎不是每个数据库问题的实用长期解决方案。我怀疑我现在遇到的问题对我来说是独一无二的。

  1. 听起来“schema_info”表和“schema_migrations”表是一样的。在我的设置中,我只有“schema_migrations”。如前所述,生产服务器上的“schema_migrations”表和开发机器上的差异只是一条记录。即包含我要迁移的更改的版本号的记录。

  2. 从我读过的《Simply Rails 2》一书中,它指出当第一次迁移到生产服务器时,应该只运行 rake:db:schema:load,而不是运行 rake db:migrate。

  3. 如果重要的话,我使用的是 Rails 2.1 版。

4

9 回答 9

1

关于您的更新:

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

    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,它会起作用。

于 2008-10-28T00:33:37.590 回答
1

根据生产中使用的系统,我看到以下情况不起作用的情况

rake db:migrate RAILS_ENV=production

但是这个确实有效:

RAILS_ENV=production rake db:migrate

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

于 2009-04-01T20:53:24.547 回答
1

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

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

于 2008-10-24T23:48:14.773 回答
1

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

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

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

于 2008-10-31T09:41:45.703 回答
0

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

于 2008-11-11T21:52:03.007 回答
0

rake db:schema:load 将从 schema.rb 加载数据库结构。该文件是数据库结构的当前表示。当您有一个需要创建所有表和索引的空模式(数据库)时使用它。它使您不必运行所有迁移。如果您有一个包含数据的现有生产数据库,您不想运行它。正如其他人所说,那会很糟糕!

于 2008-11-11T21:57:03.933 回答
0

我只想删除数据库,再次添加它并运行 rake rb:migrate。布拉德是正确的,当您运行模式加载时,它没有在 schema_migrations 表中放置任何记录。

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

于 2008-10-25T00:18:53.403 回答
0

我知道这篇文章是很久以前的,但我偶然发现它并没有真正得到答复。当它出现在谷歌上时,就到这里。

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

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

于 2009-10-21T14:00:21.927 回答
-1
rake db:migrate RAILS_ENV=production

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

于 2008-10-25T03:31:57.660 回答