Rails Migration change column используется для использования массивов Postgres
Я пытаюсь изменить столбец в моей базе данных, чтобы он мог использовать тип данных массива 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
Ответы
Ответ 1
PostgreSQL не знает, как автоматически преобразовать столбец varchar
в массив varchar
. Он не знает, что вы можете намереваться, потому что у него нет способа узнать, какой формат вы считаете текущими значениями.
Итак, вам нужно сказать это; что для предложения USING
.
ActiveRecord явно не поддерживает предложение USING
(неудивительно, поскольку он почти не поддерживает даже самые базовые функции базы данных). Однако вы можете указать свой собственный текст SQL для миграции.
Предполагая, что ваши строки разделены запятыми и могут не содержать запятых, например:
def change
change_column :table, :dummy_column, "varchar[] USING (string_to_array(dummy_column, ','))"
end
(Я не использую Rails самостоятельно и не тестировал это, но он согласуется с синтаксисом, используемым в других примерах).
Ответ 2
Использование Rails 4.2 на postgresql 9.4 Я искал это и сохранил мои ранее существовавшие строковые данные в качестве первого элемента в массивах элементов.
Оказывается, 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() )
. Вот документы на этом - отметьте, что вам нужно предоставить разделитель.
Ответ 3
def change
change_column :table, :dummy_column, :string, array: true, default: '{}'
end
Примечание:
он указан как тип данных: строка с массивом: true для столбца по умолчанию для пустого массива ([]), вы используете значение по умолчанию: '{}'
Ответ 4
Использование Rails 4.2 в postgresql 9.4 с уменьшением и увеличением, основанием для ответа 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