Rails迁移似乎已完成,但rake仍将迁移显示为挂起

时间:2017-07-26 03:16:51

标签: mysql ruby-on-rails database-migration rails-migrations mysql2

我在大型MySql2数据库上运行了一个简单的rails迁移,以向表中添加一列:

class AddMiddleNameToPerson < ActiveRecord::Migration[5.0]
  def change
    add_column :person, :middle_name, :string
  end
end

在迁移过程中,我与运行rails app的服务器断开连接。然后我重新连接并使用bundle exec rake db:migrate:status检查迁移状态,显示为已关闭:

down    20170424182410  Add middle name to person

我认为它仍然在后台运行。所以我离开了一段时间,并最终使用rails控制台我验证了person.middle_name可以在对象上访问。但是,db:migrate:status仍然会将迁移显示为已关闭,如果我再次尝试运行db:migrate,则会收到错误消息:

Mysql2::Error: Duplicate column name 'middle_name'

因此,似乎新列位于数据库中,并且可通过ActiveRecord访问,但rake db:migrate:status发现迁移为downrake db:migrate尝试重新运行它,但未成功。

1 个答案:

答案 0 :(得分:1)

如果这是一个生产数据库(或其他包含重要数据的数据库),那么不会 rake db:reset,因为这将丢弃数据库,你将失去一切;也 db:migrate:down,因为这会删除middle_name列,您将丢失已有的中间名。

首先获得数据库的备份,或者至少获得您正在使用的表格。

其次,使用mysql CLI工具连接到数据库并说出describe people;。您问题中的信息表明您会在其中看到middle_name列,但确保您连接到正确的数据库并没有什么坏处。如果middle_name不存在,那么你几乎肯定会在某个地方连接到错误的数据库,如果它存在,那么你只需要一个迁移问题来清理。

您说在迁移完成之前已删除数据库连接。迁移按以下顺序进行:

  1. 运行迁移以更新数据库。
  2. schema_migrations表中记录迁移的版本号。
  3. 重新生成db/schema.rbdb/structure.sql
  4. 如果 1 完成但连接丢失,则 2 永远不会发生,因此迁移将会运行但Rails不会知道。

    如果没有其他环境需要迁移,那么您只需删除迁移,然后rake db:schema:dumprake db:structure:dump即可获得新的schema.rbstructure.sql。迁移只是暂时的一些代码,可以让你从A到B,所以在它们运行之后删除它们很好(甚至推荐),所有重要的长期是数据库的结构(在db/schema.rb中或db/structure.sql)。

    如果其他环境需要运行迁移,那么您可以手动修补schema_migrations表;使用mysql CLI工具连接到数据库并说出insert into schema_migrations (version) values ('20170424182410');。 Rails现在知道迁移已经运行,未来的rake db:migrate电话会很高兴。然后,您需要刷新schema.rb(使用rake db:schema:dump)或structure.sql(使用rake db:structure:dump)。

    您可能有一个db/schema.rb文件用于跟踪数据库的结构(包括已运行的迁移的版本号)。如果您这样做,则使用rake db:schema:dump重新生成它。如果您有db/structure.sql,则可以使用rake db:structure:dump