Rails迁移更改列以使用Postgres数组

我试图更改我的数据库中的列,以便它可以使用Postgres数组数据类型。 目前,表列的类型为string。

我使用以下迁移来转换它:

def change change_column :table, :dummy_column, :text, array: true, default: [] end 

但是我收到以下错误:

 bundle exec rake db:migrate rake aborted! An error has occurred, this and all later migrations canceled: PG::Error: ERROR: column "dummy_column" cannot be cast automatically to type character varying[] HINT: Specify a USING expression to perform the conversion. : ALTER TABLE "table" ALTER COLUMN "dummy_column" TYPE character varying(255) Tasks: TOP => db:migrate 

PostgreSQL不知道如何自动将varchar列转换为varchar数组。 它不知道您可能想要什么,因为它无法知道您认为当前值的格式。

所以你需要告诉它; 这就是USING子句的用途。

ActiveRecord似乎没有明确支持USING子句(这并不奇怪,因为它几乎不支持最基本的数据库function)。 但是,您可以为迁移指定自己的SQL文本。

假设您的字符串以逗号分隔,并且可能不包含逗号,例如:

 def change change_column :table, :dummy_column, "varchar[] USING (string_to_array(dummy_column, ','))" end 

(我自己并没有使用Rails,也没有测试过这个,但它与其他地方的例子中使用的语法一致)。

在postgresql 9.4上使用Rails 4.2我希望这样做并保留我预先存在的字符串数据作为一个元素数组中的第一个元素。

事实certificate,postgresql不能将字符串强制转换为文本数组而没有USING表达式来告诉它如何。

在精心设计了postgres语法后,我找到了一个有活跃记录的好方法:

 def change change_column :users, :event_location, :text, array: true, default: [], using: "(string_to_array(event_location, ','))" end 

唯一的直接postgresql是(string_to_array() )函数调用。 以下是有关该文档的文档 -您必须提供分隔符。

在postgresql 9.4上使用Rails 4.2,使用向下和向上,基于lrrthomas响应。 注意:您的起始列的默认值为nil

 class ChangeEmailAndNumberColumnForContact < ActiveRecord::Migration def up change_column :contacts, :mobile_number, :text, array: true, default: [], using: "(string_to_array(mobile_number, ','))" change_column :contacts, :email, :text, array: true, default: [], using: "(string_to_array(email, ','))" end def down change_column :contacts, :mobile_number, :text, array: false, default: nil, using: "(array_to_string(mobile_number, ','))" change_column :contacts, :email, :text, array: false, default: nil, using: "(array_to_string(email, ','))" end end 
 def change change_column :table, :dummy_column, :string, array: true, default: '{}' end 

注意:

它被指定为数据类型:string with array:true默认列为空数组([]),使用默认值:'{}’