我在大型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
发现迁移为down
,rake db:migrate
尝试重新运行它,但未成功。
答案 0 :(得分:1)
如果这是一个生产数据库(或其他包含重要数据的数据库),那么不会 rake db:reset
,因为这将丢弃数据库,你将失去一切;也不 db:migrate:down
,因为这会删除middle_name
列,您将丢失已有的中间名。
首先获得数据库的备份,或者至少获得您正在使用的表格。
其次,使用mysql
CLI工具连接到数据库并说出describe people;
。您问题中的信息表明您会在其中看到middle_name
列,但确保您连接到正确的数据库并没有什么坏处。如果middle_name
不存在,那么你几乎肯定会在某个地方连接到错误的数据库,如果它存在,那么你只需要一个迁移问题来清理。
您说在迁移完成之前已删除数据库连接。迁移按以下顺序进行:
schema_migrations
表中记录迁移的版本号。db/schema.rb
或db/structure.sql
。如果 1 完成但连接丢失,则 2 永远不会发生,因此迁移将会运行但Rails不会知道。
如果没有其他环境需要迁移,那么您只需删除迁移,然后rake db:schema:dump
或rake db:structure:dump
即可获得新的schema.rb
或structure.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
。