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

发布于 2024-07-08 01:34:20 字数 1050 浏览 7 评论 0原文

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

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

我心里想,不是开玩笑吧,Rake……是你创造的! 我在 rake 上运行了跟踪,似乎 rake 认为这是它第一次运行。 但是,通过分析我的开发计算机和生产计算机上的“schema_migrations”表,您可以看到一项迁移(即我想要迁移的迁移)存在差异。

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

关于如何使我的生产服务器保持最新状态有什么想法吗?

更新:

首先我要说的是,我不能只是“删除”数据库。 它是一个生产服务器,其中已有 10 万多条记录。 如果以后再出现类似的问题怎么办? 我是不是每次数据库出现问题时就删除表? 这次可能会起作用,但它似乎并不是解决所有数据库问题的实用的长期解决方案。 我怀疑我现在遇到的问题是我独有的。

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

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

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

I have two machines... a development machine and a production machine. When I first brought my rails app onto the production server, I had no problem. I simply imported schema.rb by running rake db:schema:load RAILS_ENV=production. All was well.

So, then on my development machine, I made some more changes and another migration, and then copy the new application over to the production machine. I then tried to update the database by running rake db:migrate RAILS_ENV=production. I get the following error:
"There is already an object named 'schema_migrations' in the database."

I'm thinking to myself, ya no kidding Rake... you created it! I ran trace on rake and it seems as if rake thinks it's the first time it's ever ran. However, by analyzing my 'schema_migrations' table on my development machine and my production machine you can see that there is a difference of one migration, namely the one that I want to migrate.

I have also tried to explicitly define the version number, but that doesn't work either.

Any ideas on how I can bring my production server up to date?

Update:

Let me start off by saying that I can't just 'drop' the database. It's a production server with a little over 100k records already in it. What happens if a similar problem occurs in the future? Am, I to just drop the table every time a database problem occurs? It might work this time, but it doesn't seem like a practical long term solution to every database problem. I doubt the problem I'm having now is unique to me.

  1. It sounds like the 'schema_info' table and the 'schema_migrations' table are the same. In my setup, I only have 'schema_migrations'. As stated previously, the difference between the 'schema_migrations' table on the production server and the development machine is just one record. That is, the record containing the version number of the change I want to migrate.

  2. From the book I read, 'Simply Rails 2', it states that when first moving to a production server, instead of running rake db:migrate, one should just run rake:db:schema:load.

  3. If it matters, I'm using Rails version 2.1.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

空气里的味道 2024-07-15 01:34:20

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

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

This is a guess, I admit: I think that because you first ran db:schema:load instead of db:migrate in your production environment, you got the structure of your db, but not the data that migrate populates into your schema_info table. So now, when you run migrate in the production environment, there is no data in schema_info which is why migrate believes that it hasn't run yet (because it hasn't).

That said... you say that you have looked in the "schema_migrations" table, and that there is a difference of one version from dev to production... I haven't heard of that table, although I'm a few months behind on my rails version. Maybe you could try creating a "schema_info" table in the production environment, with a single "version" column, and add a row with the version that you believe your production environment to be on.

拒绝两难 2024-07-15 01:34:20

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

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

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

If you get "There is already an object named 'schema_migrations' in the database." error message then I suspect that you are using MS SQLServer as your database? (As this seems like MS SQL Server error message)

If yes then which ActiveRecord database adapter you are using? (What is your database.yml file, what gems have you installed to access MS SQL Server database?)

Currently it seems that Rails does not find schema_migrations table in production schema and therefore tries to create it and this creation fails with database error message. Probably the reason is upper/lower case characters in schema_migrations table name - as far as I understand MS SQL Server identifiers are case sensitive.

无所谓啦 2024-07-15 01:34:20

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

rake db:migrate RAILS_ENV=production

但是这个可以工作的地方:

RAILS_ENV=production rake db:migrate

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

Depending on the system used in production, I have seen instances where the below does not work:

rake db:migrate RAILS_ENV=production

But where this one does work:

RAILS_ENV=production rake db:migrate

Quirky, I know, but it's worth trying it to see if it makes a difference.

恬淡成诗 2024-07-15 01:34:20

关于您的更新:

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

    ActiveRecord::Base.connection.execute("INSERT schema_migrations (version) VALUES(#{我的生产版本号})")

  2. 或者,您可以尝试在生产环境中完全删除 schema_migrations 表:

    ActiveRecord::Base.connection.execute("删除表 schema_migrations")

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

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

Regarding your update:

  1. I don't understand what the difference is between your production schema_migrations and the dev version. Is there a record in both tables (there should be just 1 column, "version", right) or is there a single record in the dev DB and zero records in production? If there are zero records in the production table, then do this:

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

  2. Alternatively, you could try dropping the schema_migrations table totally on production:

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

    Then, re-running rake db:migrate RAILS_ENV=production. That will run migrations from starting from version 1 though, which is probably not what you're after.

  3. Alternatively alternatively, you could start an IRB session in your production environment, do either a "require" or "load" (I can never remember which, or if it matters) of the migration file that you want to load, and then call MyMigrationClass.up. You would need to manually set the version number in the schema_migrations table after that, as you would still have the problem going forward, but as a quick-fix type of hack, that would work.

白鸥掠海 2024-07-15 01:34:20

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

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

I would just drop the DB, add it again and run rake rb:migrate. Brad is correct that when you ran the schema load, it didn't put any records in the schema_migrations table.

This is more complicated of course if there is data you can't lose on the production server. You could get the rake backup tasks (not sure if that is part of core or not) and then run rake db:backup:write on your production database, and then after you get the migrations up to date on production, run rake db:backup:read.

剧终人散尽 2024-07-15 01:34:20

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

schema_info is from an old version of Rails. schema_migrations is the new kid on the block. You should be able to remove the schema_info table as it'll no longer be used. You'll probably want to search for any issues associated with this name change.

桃气十足 2024-07-15 01:34:20

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

rake db:schema:load will load the database structure from schema.rb. This file is the current representation of the database structure. It's used when you have an empty schema (database) that needs all the tables and indexes creating. It saves you having to run all the migrations. If you have an existing production database with data in, you don't want to run it. As others have said that would be bad!

瀞厅☆埖开 2024-07-15 01:34:20

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

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

您需要在迁移表中设置版本号才能随后运行迁移。 因此,了解您的 schema.rb 所涉及的版本也很重要,或者删除所有旧的迁移(它们安全地位于您的 SCM 中,对吗?)

I know this post was some time ago, but I stumbled across it and it hasn't really been answered. As it comes up on google, here goes.

When you did a rake db:schema:dump (or when this was done for you by the build scripts) it will have put the definition of the migrations table into the schema.rb. At the end of the script, the process will try to create the table again, however it obviously exists already. Just remove the migrations table from the schema.rb before running rake:schema:load and there will be no error message.

You will need to set the version number in the migrations table to subsequently run migrations. So it is important to know what version your schema.rb relates too, or delete all the old migrations (they're safely in your SCM right?)

生死何惧 2024-07-15 01:34:20
rake db:migrate RAILS_ENV=production

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

rake db:migrate RAILS_ENV=production

Use the db:schema:load task just for the first creation, incremental changes should be migrated.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文