我无法回滚迁移,因为迁移文件不存在



我在分支中添加了一个迁移"add_dogs"迁移db/migrate/20221220155010_create_dogs.rb,运行db:migrate

后来,我改变了分支(没有合并),最终放弃了"new_dog "分支。

后来,我查看了"add_cats"用db/migrate/20221101010101_create_cats.rb支路,用db:migrate支路。到目前为止,一切都很好。

然后我调整了"add_cats"迁移(在提交任何东西之前),并运行db:rollback,以便我可以再次运行它。我得到这个错误:

ActiveRecord::UnknownMigrationVersionError:
No migration with version number 20221220155010.

我仍然可以在新的迁移上运行db:migrate,但不能运行db:rollbackdb:migrate:redo

这是有意义的,因为数据库有应用20221220155010的记录,但是该迁移文件不再存在,所以没有办法回滚它。

我怎样才能通过这个?

根据您的需要和访问权限,有三种方法可以处理丢失的迁移文件:

  1. 对于一个快速的临时修复,您可以回滚您当前正在编辑的迁移,以便您可以再次运行它。如果另一个迁移仍然在另一个分支的管道中,并且两者最终将被合并,那么这可能是有用的。
rake db:migrate:down VERSION=20230101010101  
// This is the version of the migration you WANT to rollback, not the missing one. 
  1. 如果丢失的迁移永远不会回来,您需要永久修复。最简单的方法是从数据库中删除该记录。您可以从您最喜欢的SQL客户端、rails控制台等完成此操作(我认为您甚至可以编写迁移来完成此操作,但这似乎强大粗略。)
DELETE FROM schema_migrations WHERE version = '20221220155010'
-- This is the version of the migration that is MISSING, not the one you are working on.
  1. 如果由于某种原因不能直接访问数据库,可以给Rails一个回滚的安慰剂。确保文件名中的时间戳与丢失的迁移版本号匹配。

创建名为db/migrations/20221220155010_just_kidding.rb:

的文件
class JustKidding < ActiveRecord::Migration
def change
# nothing to see here.
end
end

然后,rails db:rollback将回滚该无操作迁移,并从schema_migrations表中删除20221220155010。现在,您可以永远删除安慰剂迁移,并且您将在运行迁移和回滚方面处于良好状态。

然而…不要忘记,旧迁移的效果仍然在您的模式中。也许你遇到了一个新的、未使用过的"dogs"表,或者表上多了一列。也许这在您的开发设备上是无害的,但您肯定不希望在生产环境中出现这种乱七八糟的东西。这个答案中的所有建议都假设您处于一个一次性环境中,并且旧迁移的影响不是问题。在这种情况下,拆除整个数据库并重新构建可能是一个更有吸引力的选择。

这里真正的收获之一是……首先不要让这种情况发生!理想情况下,您应该在从分支更改之前回滚任何新的、未提交的迁移。但是…事情发生…

注。如果有办法从命令行做到这一点,我很乐意学习。我想象rails db:migrate:delete VERSION=20230101010101这样的东西可能会以一种hackish的方式方便。

相关内容

最新更新