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