Миграция Rails - изменить столбец с varchar на jsonb

Я пытаюсь преобразовать существующий столбец типа varchar в jsonb. Столбец содержит такие строки, как «черный белый оранжевый», и вы хотите преобразовать его в формат jsonb, чтобы он был преобразован в [«черный», «белый», «оранжевый»].

class AlterColorsDatatype < ActiveRecord::Migration[5.0]
  def change
    change_column :quotes, :colors, :jsonb, default: '[]', using: 'colors::jsonb'
  end
end

Я ожидал, что это преобразует тип столбца в jsonb, а часть using: также преобразует существующие данные в jsonb.

Вместо этого я получаю эту ошибку:

ActiveRecord :: StatementInvalid: PG :: InvalidTextRepresentation: ОШИБКА: недопустимый синтаксис ввода для типа json. ДЕТАЛИ: токен «Индиго» недействителен. КОНТЕКСТ: данные JSON, строка 1: Индиго: ALTER TABLE "кавычки" ALTER COLUMN "цвета" ТИП jsonb ИСПОЛЬЗОВАНИЕ цветов :: jsonb

Я пробовал другой синтаксис, но все равно получаю ту же ошибку. Я думаю, мне придется преобразовать весь атрибут столбца по атрибуту во что-то вроде to_json, но я не уверен, как подойти к решению этой ошибки. После многих поисков в Google другие люди с той же ошибкой, похоже, не нашли решения.


person Alex F    schedule 11.12.2017    source источник


Ответы (1)


Вы не можете перейти от строки, разделенной пробелами, к JSON с помощью простого преобразования. Простой способ - сначала разбить строку, чтобы получить массив PostgreSQL (text[]):

regexp_split_to_array(colors, E'\\s+')

а затем преобразовать этот массив в JSON:

to_json(regexp_split_to_array(colors, E'\\s+'))

Вы должны быть осторожны с кавычками и обратной косой чертой, чтобы получить этот бит SQL через Ruby и в базу данных, чтобы вы сказали:

using: %q{to_json(regexp_split_to_array(colors, E'\\\\s+'))}

%q{...} похож на строку в одинарных кавычках, но позволяет избежать необходимости экранировать одинарные кавычки в строковом литерале SQL, а затем удваивать обратную косую черту, чтобы они не интерпретировались %q{...}.

person mu is too short    schedule 11.12.2017