Ruby on Rails迁移:将字符串转换为十进制数

4

我已经创建了一个数据库,并向其中输入了大约30-40个条目。但是出现了错误,我不小心将数据库的某些列设置为字符串,而我需要它们是小数以便对它们进行操作。

为了更改数据库,我生成了一个迁移文件来实现这一点。

class ChangeOddsAndUnitsColumn < ActiveRecord::Migration
  def change
    change_column :bets, :units_placed, :decimal
    change_column :bets, :odds, :decimal
  end
end

然而,当我运行rake db:migrate时,出现以下错误。
PG::DatatypeMismatch: ERROR:  column "units_placed" cannot be cast automatically to type numeric

每列中的值已经是十进制数了,但我无法想出如何将它们从字符串转换为十进制类型。
2个回答

2
What you need to do is an atomic operation, where you first delete the column that will not be used. Then create a decimal type column. Finally, update the table and assign values. If you do not want to lose information, you should back it up and then use a SQL update procedure to convert types. I hope this serves as a guide. Greetings.
class ChangeOddsAndUnitsColumn < ActiveRecord::Migration
  def up
    change_table :bets do |t|
      t.decimal :units_placed, precision: 16, scale: 2
    end
    Bets.update_all ["units_placed = ?", 0.0]
  end

  def down
    remove_column :bets, :units_placed
  end
end

4
请在此网站上使用英语。 - Aleksei Matiushkin

1
在我的情况下,使用Rails 6时,我所做的是(类型转换)。
class StringToDecimalConverter < ActiveRecord::Migration[6.0]
 def up
   change_column_default :table, :attr, nil
   change_column :table, :attr, "decimal USING CAST( attr AS decimal)"
   change_column :table, :attr, :decimal, precision: 21, scale: 3, default: 0.0    
 end

 def down
   change_column :table, :attr, :string, default: "0"
 end
end

在我的情况下,原因是:
change_column_default :table, :attr, nil

如果您设置了默认值,则无法自动转换,因此首先将其设置为nil可以解决这个问题。
精度也无法在同一change_column行中设置。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接