执行rake db:migrate触发StandardError,提示books表已存在
解决Rake DB迁移时"Table 'books' already exists"的报错
这个问题我碰到过好多次,本质就是你的MySQL数据库里已经存在books表了,但你的20180407084831版本迁移脚本还在尝试创建它,导致冲突触发Mysql2错误,后续迁移也被终止了。下面给你几个靠谱的解决方案,你可以根据自己的情况选:
方案1:删除现有表后重新迁移(适合不需要保留表数据的情况)
如果这个books表是之前误操作或者手动创建的,里面没有需要保留的数据,那直接删表再跑迁移就行:
- 登录到你的MySQL控制台:
mysql -u 你的用户名 -p - 切换到你的Rails应用数据库:
USE 你的数据库名; - 删除
books表:DROP TABLE books; - 回到终端重新执行迁移:
rake db:migrate
方案2:标记迁移为已执行(适合需要保留表数据的情况)
如果books表的数据很重要不能删,那可以让Rails认为这个迁移已经完成了,不需要再执行创建表的操作:
- 同样登录MySQL控制台,切换到应用数据库后,执行这条SQL把迁移版本号加入到
schema_migrations表中:INSERT INTO schema_migrations (version) VALUES ('20180407084831'); - 或者用Rails自带的命令(部分Rails版本支持):
rake db:migrate:mark_as_up VERSION=20180407084831 - 之后再执行
rake db:migrate就会跳过这个迁移,继续执行后面的任务了。
方案3:修改迁移脚本(避免以后再出现类似问题)
如果你想从根源解决,防止下次迁移再踩坑,可以修改20180407084831对应的迁移文件,给create_table加上if_not_exists: true参数(Rails 5及以上版本支持):
class CreateBooks < ActiveRecord::Migration[5.0] def change create_table :books, if_not_exists: true do |t| t.string :title, limit: 32, null: false t.float :price t.integer :subject_id t.text :description t.timestamp :created_at end end end
修改后再执行rake db:migrate就不会因为表已存在报错了。
注意:不管选哪个方案,操作数据库前最好先备份一下数据,避免意外丢失重要信息!
内容的提问来源于stack exchange,提问作者Sania Parween
相关产品推荐
相关产品推荐

