Rails Migration changing column to use Postgres arrays

后端 未结 5 1639
故里飘歌
故里飘歌 2020-12-14 03:28

I am trying to change a column in my database so that it can use the Postgres array data type. Currently the table column is of type string.

I am using the following

相关标签:
5条回答
  • 2020-12-14 03:39

    Using Rails 4.2 on postgresql 9.4 with a down and a up, base on lrrthomas response. Note: your starting column should have a default of 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
    
    0 讨论(0)
  • 2020-12-14 03:49

    It can be done like below:

    change_column :table, :column, :string, array: true, default: {}, using: "(string_to_array(column, ','))"
    
    0 讨论(0)
  • 2020-12-14 03:53
    def change
    
        change_column :table, :dummy_column, :string, array: true, default: '{}'
    
    end
    

    Notice:

    it's specified as data type :string with array: true to default the column to an empty array ( [] ), you use default: '{}'

    0 讨论(0)
  • 2020-12-14 03:55

    PostgreSQL doesn't know how to automatically convert a column of varchar into an array of varchar. It doesn't know what you might intend, because it has no way to know what format you think the current values are in.

    So you need to tell it; that's what the USING clause is for.

    ActiveRecord doesn't seem to explicitly support the USING clause (not surprising, as it barely supports even the most basic database features). You can specify your own SQL text for the migration, though.

    Assuming your strings are comma separated and may not themselves contain commas, for example:

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

    (I don't use Rails myself and haven't tested this, but it's consistent with the syntax used in examples elsewhere).

    0 讨论(0)
  • 2020-12-14 03:57

    Using Rails 4.2 on postgresql 9.4 I was looking to do this and preserve my pre-existing string data as the first element in one element arrays.

    It turns out that postgresql cannot coerce a string into a text array without a USING expression to tell it how.

    After much fiddling with delicate postgres syntax, I found a good middle way with active record:

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

    The only direct postgresql there is the (string_to_array() ) function call. Here are the docs on that--note that you have to supply a delimiter.

    0 讨论(0)
提交回复
热议问题