将布尔列类型更改为 int
Changing boolean column type to int
我的 Postgres 数据库 table 中有一列是布尔类型。我想将它更改为整数,因为我需要的不仅仅是该列中的 true/false。
我也想把所有的真值改成1,假值改成2。
这在 Rails 中很容易完成吗?我试图通过迁移文件和迁移我的数据库来做到这一点。
你真的需要为此修改数据库吗?一种可能的解决方案是只创建一个包装器方法来为您处理这个问题。假设您有一个名为 mycol
的布尔列,那么您可以只编写一个包装方法来透明地处理此逻辑,而无需修改底层数据库。
在您的 ActiveRecord 模型中:
def mycol
read_attribute(:boolcol) ? 1 : 2
end
def mycol=(value)
write_attribute(:mycol, value == 1)
end
例如,运行 u.mycol = 1 && u.save
将 false
写入数据库,而 u.reload.mycol 将 return 1.
但是,如果确实有必要进行迁移,则创建一个新的整数列来取代原来的布尔列。不要删除或修改现有列,因为要确保您没有损坏或破坏数据。
创建新列后,创建一个 rake 任务来遍历所有现有记录(使用 find_each
方法进行迭代)并根据值设置新列的整数值原始布尔列。验证数据的完整性后,您可以删除原始布尔列并将其替换为新创建的列。
是的,您可以通过一次迁移完成此更改。唯一棘手的部分是需要告诉数据库如何将布尔值转换为整数。
这样做的方法是在 ALTER TABLE
中使用 USING
子句来提供映射。原始 SQL 版本看起来像这样:
alter table models
alter column c type integer
using case when c then 1 else 2 end
因此转化为迁移:
def change
change_column :models, :c, :integer, :using => 'case when c then 1 else 2 end'
end
布尔列只能包含 TRUE
或 FALSE
,因此简单的 CASE
就足够了。如果您允许 NULL
s 并希望保留它们,那么:
:using => 'case when c is null then null when c then 1 else 2 end'
应该可以解决问题。
当然,您必须更新所有代码才能正确地手动处理这些新整数。
我的 Postgres 数据库 table 中有一列是布尔类型。我想将它更改为整数,因为我需要的不仅仅是该列中的 true/false。
我也想把所有的真值改成1,假值改成2。
这在 Rails 中很容易完成吗?我试图通过迁移文件和迁移我的数据库来做到这一点。
你真的需要为此修改数据库吗?一种可能的解决方案是只创建一个包装器方法来为您处理这个问题。假设您有一个名为 mycol
的布尔列,那么您可以只编写一个包装方法来透明地处理此逻辑,而无需修改底层数据库。
在您的 ActiveRecord 模型中:
def mycol
read_attribute(:boolcol) ? 1 : 2
end
def mycol=(value)
write_attribute(:mycol, value == 1)
end
例如,运行 u.mycol = 1 && u.save
将 false
写入数据库,而 u.reload.mycol 将 return 1.
但是,如果确实有必要进行迁移,则创建一个新的整数列来取代原来的布尔列。不要删除或修改现有列,因为要确保您没有损坏或破坏数据。
创建新列后,创建一个 rake 任务来遍历所有现有记录(使用 find_each
方法进行迭代)并根据值设置新列的整数值原始布尔列。验证数据的完整性后,您可以删除原始布尔列并将其替换为新创建的列。
是的,您可以通过一次迁移完成此更改。唯一棘手的部分是需要告诉数据库如何将布尔值转换为整数。
这样做的方法是在 ALTER TABLE
中使用 USING
子句来提供映射。原始 SQL 版本看起来像这样:
alter table models
alter column c type integer
using case when c then 1 else 2 end
因此转化为迁移:
def change
change_column :models, :c, :integer, :using => 'case when c then 1 else 2 end'
end
布尔列只能包含 TRUE
或 FALSE
,因此简单的 CASE
就足够了。如果您允许 NULL
s 并希望保留它们,那么:
:using => 'case when c is null then null when c then 1 else 2 end'
应该可以解决问题。
当然,您必须更新所有代码才能正确地手动处理这些新整数。