如何将字符串列更改为bigint?
在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
还是一样的错误。
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
您的ip_number_from列中有什么?
无论如何,我可能会:
- 创建一个bigint类型的新列,
- 通过rails console或rake任务手动将数据从ip_number_from复制到new_column,
- 删除原始ip_number_from列
- 将new_column重命名为ip_number_from
或者你可以下载到SQL,就像mjtko建议的那样,但我不确定它会更容易。
更新
我抬头看着尤尔的建议。 我认为在一次迁移中完成所有这些操作会有点危险,因为您无法真正检查数据的转换/复制是否成功。 如果您确实希望在一次迁移中执行此操作,则在您的情况下,它看起来像这样:
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
您还应该添加相应的向下迁移。
您可以随时在多次迁移中将其拆分,并随时检查进度/成功。
我最近读过 – 但不记得在哪里 – 你不能将“字符串”列转换为“int”列,但你可以做相反的事情。 从“int”到“string”的转换是不可逆转的迁移操作。
我将在我阅读的文档中搜索并在我找到它时编辑我的post。
如果可以的话,最简单的事情就是Jure Triglav所建议的。 (他在我之前发布了他的答案,但我建议同样的事情;))。
[编辑]我发现了我读到的地方: 不可逆转移tuto 。