如何将字符串列更改为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 。