在rails迁移中。如何将字符串类型列更改为bigint?
我有:
t.change :ip_number_from, :integer, :limit => 8
我明白了:
PG::Error: ERROR: column "ip_number_from" cannot be cast to type bigint
我甚至尝试过两种选择:
change_column :ip_to_countries, :ip_number_from, :integer, :limit => 8
change_column :ip_to_countries, :ip_number_from, :bigint
仍然是同样的错误。
答案 0 :(得分:13)
Postgres告诉你,该列中存在不知道如何转换的现有数据,因此它需要一个ALTER语句,该列为列提供USING子句以指定如何转换现有值。
不幸的是,您需要删除特定于数据库的代码来完成此操作,或者使用与此处建议的解决方案类似的内容:
http://webjazz.blogspot.co.uk/2010/03/how-to-alter-columns-in-postgresql.html
编辑:以下是您在迁移中直接在SQL中执行此操作的方法:
execute <<-SQL
ALTER TABLE ip_to_countries
ALTER COLUMN ip_number_from TYPE bigint USING ip_number_from::bigint
SQL
答案 1 :(得分:3)
你的ip_number_from列是什么?
无论如何,我可能会:
或者你可以像mjtko建议的那样下载到SQL,但我不确定它会更容易。
我抬头看着尤尔的建议。我认为在一次迁移中完成所有这些操作会有点危险,因为您无法真正检查数据的转换/复制是否成功。如果您确实希望在一次迁移中执行此操作,则在您的情况下,它看起来像这样:
def up
add_column :table, :new_column, :bigint
Model.reset_column_information
Model.all.each do |m|
m.update_attribute :new_column, Model.bigint_from_ip_number_from(m)
end
drop_column :table, :ip_number_from
rename_column :table, :new_column, :ip_number_from
end
您还应该添加相应的向下迁移。
您可以随时将其拆分为多次迁移,并随时查看进度/成功情况。
答案 2 :(得分:0)
我最近读过 - 但不记得在哪里 - 你不能将“字符串”列转换为“int”列,但你可以这样做。从“int”到“string”的转换是不可逆转的迁移操作。
我将在我阅读的文档中搜索并在我找到它时编辑我的帖子。
如果可以的话,最容易做的就是Jure Triglav的建议。 (他在我之前发布了他的答案,但我建议同样的事情;))。
[编辑]我发现我回读的地方:Irreversible Migration tuto。
答案 3 :(得分:0)
change_column :table_name, :column_name, 'TYPE bigint USING CAST(column_name AS TYPE bigint)'