回滚失败的Rails迁移(Rolling back a failed Rails migration)

编程入门 行业动态 更新时间:2024-10-26 16:21:02
回滚失败的Rails迁移(Rolling back a failed Rails migration)

如何回滚失败的rails迁移? 我会期望rake db:rollback可以撤消失败的迁移,但不会,它回滚以前的迁移(失败的迁移减去一个)。 和rake db:migrate:down VERSION=myfailedmigration也不起作用。 我已经遇到了这几次,这是非常令人沮丧的。 这是一个简单的测试,我想重复的问题:

class SimpleTest < ActiveRecord::Migration def self.up add_column :assets, :test, :integer # the following syntax error will cause the migration to fail add_column :asset, :test2, :integer end def self.down remove_column :assets, :test remove_column :assets, :test2 end end

结果:

== SimpleTest: migrating ===================================================== -- add_column(:assets, :test, :integer) -> 0.0932s -- add_column(:asset, :error) rake aborted! An error has occurred, all later migrations canceled: wrong number of arguments (2 for 3)

好的,让它回滚:

$ rake db:rollback == AddLevelsToRoles: reverting =============================================== -- remove_column(:roles, :level) -> 0.0778s == AddLevelsToRoles: reverted (0.0779s) ======================================

是吧? 这是我在SimpleTest之前的最后一次迁移,而不是失败的迁移。 (而且,如果迁移输出包含版本号,那将会很好)

所以让我们尝试运行下来的失败的迁移SimpleTest:

$ rake db:migrate:down VERSION=20090326173033 $

没有任何事情发生,也没有输出。 但也许它运行迁移? 所以可以修复SimpleTest迁移中的语法错误,并尝试再次运行它。

$ rake db:migrate:up VERSION=20090326173033 == SimpleTest: migrating ===================================================== -- add_column(:assets, :test, :integer) rake aborted! Mysql::Error: Duplicate column name 'test': ALTER TABLE `assets` ADD `test` int(11)

不。 显然迁移:下来不行。 这不是失败,它只是不执行。

除了手动进入数据库并删除它,然后运行测试,没有办法摆脱那个重复的表。 必须有一个比这更好的方法。

How do you roll back a failed rails migration? I would expect that rake db:rollback would undo the failed migration, but no, it rolls back the previous migration (the failed migration minus one). And rake db:migrate:down VERSION=myfailedmigration doesn't work either. I've ran into this a few times and it's very frustrating. Here's a simple test I made to duplicate the problem:

class SimpleTest < ActiveRecord::Migration def self.up add_column :assets, :test, :integer # the following syntax error will cause the migration to fail add_column :asset, :test2, :integer end def self.down remove_column :assets, :test remove_column :assets, :test2 end end

result:

== SimpleTest: migrating ===================================================== -- add_column(:assets, :test, :integer) -> 0.0932s -- add_column(:asset, :error) rake aborted! An error has occurred, all later migrations canceled: wrong number of arguments (2 for 3)

ok, lets roll it back:

$ rake db:rollback == AddLevelsToRoles: reverting =============================================== -- remove_column(:roles, :level) -> 0.0778s == AddLevelsToRoles: reverted (0.0779s) ======================================

huh? that was my last migration before SimpleTest, not the failed migration. (And oh, it would be nice if the migration output included the version number.)

So lets try running the down for the failed migration SimpleTest:

$ rake db:migrate:down VERSION=20090326173033 $

Nothing happens, and no output either. But maybe it ran the migration anyway? So lets fix the syntax error in the SimpleTest migration, and try to run it again.

$ rake db:migrate:up VERSION=20090326173033 == SimpleTest: migrating ===================================================== -- add_column(:assets, :test, :integer) rake aborted! Mysql::Error: Duplicate column name 'test': ALTER TABLE `assets` ADD `test` int(11)

Nope. Obviously the migrate:down didn't work. It's not failing, it's just not executing.

No way to get rid of that duplicate table other than manually going into the database and removing it, and then running the test. There's got to be a better way than that.

最满意答案

不幸的是,您必须手动清理MySQL的失败迁移。 MySQL不支持事务数据库定义更改。

Rails 2.2包括PostgreSQL的事务迁移。 Rails 2.3包括SQLite的事务迁移。

这不是真的有助于您解决您的问题,但如果您在未来的项目中选择了数据库,我建议使用支持事务DDL的一个,因为它使迁移更加愉快。

更新 - 这仍然是在2017年,在Rails 4.2.7和MySQL 5.7,由Alejandro Babio在另一个答复报道。

Unfortunately, you must manually clean up failed migrations for MySQL. MySQL does not support transactional database definition changes.

Rails 2.2 includes transactional migrations for PostgreSQL. Rails 2.3 includes transactional migrations for SQLite.

This doesn't really help you for your problem right now, but if you have a choice of database on future projects, I recommend using one with support for transactional DDL because it makes migrations much more pleasant.

Update - this is still true in 2017, on Rails 4.2.7 and MySQL 5.7, reported by Alejandro Babio in another answer here.

更多推荐

本文发布于:2023-08-04 23:02:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1424472.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:Rolling   Rails   migration   failed

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!