Rails当你运行一个数据库回滚错误:ActiveRecord::IrreversibleMigration exception

最近rails3.2在更改数据库表字段,然后要回滚取消,但在运行rake db:rollback命令,错误:

rake aborted!
An error has occurred, all later migrations canceled:
ActiveRecord::IrreversibleMigration/usr/local/rvm/gems/ruby-1.9.3-p392/gems/activerecord-3.2.14/lib/active_record/migration/command_recorder.rb:42:in `block in inverse'

我的migration内容例如以下:

class ChangeVmTempColumns < ActiveRecord::Migration
  def change
    change_table :vm_temps do |t|
      t.change :disksize, :integer, :limit => 8
      t.change :mem_total, :integer, :limit => 8
    end
  end
end

上网查了资料,貌似原因在于假设在migration中做的数据类型转换是破坏性的时,就不能完毕回滚。

也就是说,对数据库表的字段类型进行改动时。数据库中的数据也会有变化,这样不能回滚这些变动的数据。

The migration that cannot be undone: Irreversible Migration》文章中举了一个样例:当我们在migration中change_column由integer变为string时是能够的,可是假设反过来。字段类型由string变为integer,我们就不能reverse
this migration。正好和我这样的情况一致!

Stackoverflow上,这个问题《ActiveRecord::IrreversibleMigration exception
when reverting migration
》提供了一个解决的方法:把self.change改为self.up和self.down方法。

改动后的migration:

class ChangeVmTempColumns < ActiveRecord::Migration
  def self.up
    change_table :vm_temps do |t|
      t.change :disksize, :integer, :limit => 8
      t.change :mem_total, :integer, :limit => 8
    end
  end

  def self.up
    change_table :vm_temps do |t|
      t.change :disksize, :string
      t.change :mem_total, :string
    end
  end
end

运行rake db:rollback,成功!

原因:我原来觉得在Rails中,self.change方法直接把self.up和self.down两个综合在一起,运行和回滚仅仅用一个change方法就能够,可是经过这个样例,我觉得self.change方法运行回滚时。仅仅能採用默认的方式运行,一旦出现上述类型转换的问题就无法正常运行。可是self.down方法运行回滚时。会强制运行self.down声明,所以没有irreversible migration错误。

版权声明:本文博客原创文章,博客,未经同意,不得转载。

时间: 2024-10-11 14:37:46

Rails当你运行一个数据库回滚错误:ActiveRecord::IrreversibleMigration exception的相关文章

Rails执行数据库回滚时报错:ActiveRecord::IrreversibleMigration exception

最近在rails3.2下修改数据库表的字段,然后想回滚取消操作,但是在执行rake db:rollback命令时,出现错误: rake aborted! An error has occurred, all later migrations canceled: ActiveRecord::IrreversibleMigration/usr/local/rvm/gems/ruby-1.9.3-p392/gems/activerecord-3.2.14/lib/active_record/migra

oracle数据库回滚

线下测试数据误操作,回滚攻略--把数据捞出来,这个时间自己设置--表名一定要是:xx_tbd日期 CREATE TABLE user_tbd0718ASselect * from user as of timestamp to_timestamp('2013-8-12 17:40:00','yyyy-mm-dd hh24:mi:ss');--清空原有表DELETE FROM user;--把捞出来的数据,填回去INSERT INTO user SELECT * FROM  user_tbd071

Spring学习笔记——Spring事务只对运行时异常回滚

我们在使用Spring时候一般都知道事务在遇到异常的时候会回滚,岂不知Spring的事务默认只有在发生运行时异常即:RunTimeException时才会发生事务,如果一个方法抛出Exception或者Checked异常Spring的事务并不会回滚. 下面我们来看看异常的分类,异常一般分为Checked异常和RunTime异常. CheckedException: Java认为Checked异常都是可以被处理的异常,所以Java程序必须显式的处理Checked异常,如果程序没有处理checked

mysql数据库回滚

在应用$mysqli时,因没常用到数据回滚,老忘,整理下,做个记录. $mysqli->autocommit(FALSE);//自动提交设置关闭 $mysqli->query("BEGIN"); //事务开始,接着下面的执行才可以我们自己控制 try{  $mysqli->query($sql);  $q1 = $mysqli->affected_rows;  if($q == 1){ //从返回的数据库影响行数做判断,是否返回正常   $mysqli->

数据库回滚解决删除数据库出错

use master go alter database OuAnFind set single_user with rollback immediate --将数据库回滚到原始配置状态 go drop database OuAnFind go

解决maven不能升级为web 3.0和jdk版本因update回滚错误

第一个问题的解决是因为版本号与配置文件不匹配造成的,解决办法是到项目下的.setting目录,修改org.eclipse.wst.common.project.facet.core.xml文件中的版本号,如下图: 还要修改web.xml的版本 2.3:<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-

springmvc事务回滚失效

转载:http://blog.csdn.net/z69183787/article/details/37819831 前文提到,最新换了框架,新项目用SpringMVC + Spring JdbcTemplate.搭框架时,发现了一个事务无法正常回滚的问题,记录如下: 首先展示问题: Spring applicationContext.xml配置: [html] view plaincopy <bean id="dataSource" class="org.spring

git代码回滚:Reset、Checkout、Revert的选择

代码回滚:Reset.Checkout.Revert的选择 Zhongyi Tong edited this page on Dec 8, 2015 · 5 revisions Pages 19 Home 2.1 快速指南 2.2 创建代码仓库 2.3 保存你的更改 2.4 检查仓库状态 2.5 检出之前的提交 2.6 回滚错误的修改 2.7 重写项目历史 3.2 保持同步 3.3 创建Pull Request 3.4 使用分支 3.5 常见工作流比较 4.1 图解Git命令 5.1 代码合并:

【Java EE 学习第19天】【使用过滤器实现全站压缩】【使用ThreadLocal模式解决跨DAO事务回滚问题】

一.使用过滤器实现全站压缩 1.目标:对网站的所有JSP页面进行页面压缩,减少用户流量的使用.但是对图片和视频不进行压缩,因为图片和视频的压缩率很小,而且处理所需要的服务器资源很大. 2.实现原理: (1)使用GZIPOutputStream工具对数据进行压缩,中间借助了ByteArrayOutputStream类进行结果的存储. (2)使用过滤器对浏览器请求进行拦截,通过自定义HttpServletResponse类(使用包装模式),重写getWriter方法,使得写出的目的地转变成ByteA