【问题标题】:Changing the data type of an entire column in a PostgreSQL DB in Rails 3.2.8在 Rails 3.2.8 中更改 PostgreSQL 数据库中整个列的数据类型
【发布时间】:2013-01-01 02:51:54
【问题描述】:

我有一个用于 Rails 3.2.8 应用程序的数据库表作为 PostgreSQL 数据库。在这个数据库中,我有一列类型为boolean。该列已填充​​值。我想将值从 boolean 更改为所有字符串。

我发现我可以运行迁移来更改列的类型。但是,我还不想这样做,因为我不确定运行此类迁移时值会发生什么。那么booleanfalse 是否会更改为“False”,布尔值true 是否会更改为“True”?

如果不是,那么完成这项任务的最佳方法是什么?

【问题讨论】:

  • 这是一个生产数据库吗?

标签: ruby-on-rails ruby postgresql activerecord attributes


【解决方案1】:

你可能会得到'true''false'

psql> create table t (c boolean not null);
psql> insert into t (c) values (TRUE), (FALSE);
psql> alter table t alter column c type text;
psql> select * from t;
   c   
-------
 true
 false

我不确定这是否得到保证,并且我找不到关于布尔到文本转换的作用的权威参考,因此您可能想检查这些在您的 PostgreSQL 版本中必须说明的内容:

psql> select TRUE::text;
psql> select FALSE::text;

如果你想保证'True''False'那么你可以使用USING手动指定转换:

可选的USING 子句指定如何从旧列值计算新列值;如果省略,则默认转换与从旧数据类型到新数据类型的赋值转换相同。

所以你可以这样说来强迫这个问题:

alter table t
alter column c type text
using case c when TRUE then 'True' when FALSE then 'False' else NULL end

如果您让 Rails 使用标准迁移进行转换,那么您将获得默认的布尔到文本转换,如果您使用 SQL ALTER TABLE 手动更改类型,那么您可以控制发生的情况。您可以在迁移中执行任一操作:

def up
    change_column :t, :c, :text
end

def up
    connection.execute(%q{
        alter table ...
    })
end

顺便说一句,我不得不质疑为文本列放弃布尔列的逻辑,这对我来说似乎有点倒退。

【讨论】:

    【解决方案2】:

    你应该没问题:

    change_column :table_name, :column_name, :string
    

    我刚刚在 9.1 上尝试过。只需备份它pg_dump test_db > test.sql

    您可以在测试表上模拟 sql 以查看您的 Postgresql 版本将如何反应,rails 应该会生成类似的东西

    ALTER TABLE my_table ALTER COLUMN col TYPE varchar(128);
    

    【讨论】:

      猜你喜欢
      • 2014-05-18
      • 2021-07-26
      • 2012-12-16
      • 2015-07-10
      • 2019-04-29
      • 1970-01-01
      • 2011-11-02
      • 1970-01-01
      相关资源
      最近更新 更多