【问题标题】:Rails Migration changing column to use Postgres arraysRails Migration 更改列以使用 Postgres 数组
【发布时间】:2014-04-28 07:22:24
【问题描述】:

我正在尝试更改我的数据库中的一列,以便它可以使用 Postgres 数组数据类型。 目前表格列是字符串类型。

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

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

【问题讨论】:

  • 您可以使用 change_column :table, :dummy_column, :string, array: true, default: [] 而不是 text 它可以解决您的问题

标签: ruby-on-rails ruby postgresql migration


【解决方案1】:

可以这样做:

change_column :table, :column, :string, array: true, default: {}, using: "(string_to_array(column, ','))"

【讨论】:

【解决方案2】:

基于 lrrthomas 响应,在 postgresql 9.4 上使用 Rails 4.2,上下移动。 注意:您的起始列应默认为 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

【讨论】:

    【解决方案3】:

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

    事实证明,如果没有 USING 表达式,postgresql 无法将字符串强制转换为文本数组。

    在对微妙的 postgres 语法进行了多次摆弄之后,我找到了一个很好的主动记录中间方法:

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

    唯一直接的 postgresql 是 (string_to_array() ) 函数调用。 Here are the docs on that--注意你必须提供一个分隔符。

    【讨论】:

      【解决方案4】:

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

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

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

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

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

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

      【讨论】:

        【解决方案5】:
        def change
        
            change_column :table, :dummy_column, :string, array: true, default: '{}'
        
        end
        

        注意:

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

        【讨论】:

        • 这对我不起作用,我之前确实尝试过。我得到同样的错误。
        • @ril 抱歉,我不知道你为什么会遇到同样的问题,但我已经在我的本地系统中尝试过了
        • 可能是 rails 版本 - 只有 Rails 4 支持吗?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-06-27
        • 1970-01-01
        • 1970-01-01
        • 2015-07-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多