Rails:将列从十进制迁移到整数后,数据会发生什么

时间:2013-01-19 20:13:24

标签: ruby-on-rails postgresql migration

我总是冒险破坏我的开发数据库(PostgreSQL)&重建它,但我想先问一下是否有人有经验。

理想情况下,所有数据都会被截断为整数:(例如:5.7会变为5)或者它可能会舍入值(5.7变为6)?或者它只是使所有值无效或清零,数据丢失?我认为最糟糕的结果是不可靠的数据(5.7变为23)。

这些类型的迁移是否有一般的经验法则?

class ChangeBookFromDecimalToInteger < ActiveRecord::Migration
  def self.up
   change_column :book, :price, :integer
  end

  def self.down
   change_column :book, :price, :decimal
  end
end

3 个答案:

答案 0 :(得分:7)

ActiveRecord将向数据库发送ALTER TABLE ALTER COLUMN ... TYPE,数据库将执行类型转换。 PostgreSQL将使用decimal将<{1}}转换为int

round

请注意round(numeric)舍入到最接近的整数。

如果您想要特定的转换行为,您应该在ALTER TABLE中使用USING这样说:

  

可选的=> create table with_decimal (n decimal(11, 6)); => insert into with_decimal (n) values (1.0),(1.1),(1.5),(1.6),(1.9); => insert into with_decimal (n) values (-1.0),(-1.1),(-1.5),(-1.6),(-1.9); => select * from with_decimal; n ----------- 1.000000 1.100000 1.500000 1.600000 1.900000 -1.000000 -1.100000 -1.500000 -1.600000 -1.900000 (10 rows) => alter table with_decimal alter column n type int; => select * from with_decimal; n ---- 1 1 2 2 2 -1 -1 -2 -2 -2 (10 rows) 子句指定如何从旧的计算新列值;如果省略,则默认转换与从旧数据类型转换为new的赋值相同。如果没有从旧类型到新类型的隐式或赋值转换,则必须提供USING子句。

如果您需要USING子句,则必须手动发出ALTER TABLE,因为ActiveRecord对USING一无所知,例如:

USING

答案 1 :(得分:0)

您需要查阅PostreSQL手册,了解它如何处理“ALTER TABLE ... CHANGE COLUMN ...”之类的查询以及它如何在相应类型之间转换数据。
Rails中的所有DB Schema更改迁移都由相应的数据库后端处理。

答案 2 :(得分:0)

一般的经验法则是,如果您将不得不迁移,并且需要明确的要求,请创建新列,使用Ruby转换列,然后删除旧列。如果您不关心数据,请让DB通过ALTER TABLE

进行操作