回滚失败的Rails迁移 [英] Rolling back a failed Rails migration

查看:72
本文介绍了回滚失败的Rails迁移的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何回滚失败的Rails迁移?我希望rake db:rollback会撤消失败的迁移,但是不会,它会回滚之前的迁移(失败的迁移减去一个).而且rake db:migrate:down VERSION=myfailedmigration也不起作用.我已经遇到过几次了,这非常令人沮丧.这是我做的一个简单的测试,可以重现该问题:

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

结果:


==  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之前的最后一次迁移,而不是失败的迁移. (哦,如果迁移输出中包含版本号,那就太好了.)

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.)

因此,让我们尝试对失败的迁移SimpleTest进行停机:

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


$ rake db:migrate:down VERSION=20090326173033
$

什么也没有发生,也没有输出.但是也许它还是进行了迁移吗?因此,让我们修复SimpleTest迁移中的语法错误,然后尝试再次运行它.

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)

不.显然,migrate:down无效.它没有失败,只是没有执行.

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不支持事务数据库定义更改.

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

Rails 2.2包括针对PostgreSQL的事务性迁移. Rails 2.3包括针对SQLite的事务迁移.

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

这现在并不能真正解决您的问题,但是,如果您可以在将来的项目中选择数据库,我建议使用一个支持事务性DDL的数据库,因为它使迁移更加轻松.

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.

更新-在2017年的Rails 4.2.7和MySQL 5.7上仍然如此,这是Alejandro Babio在此处的另一个回答.

这篇关于回滚失败的Rails迁移的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆