Errors
Trino

Trino: How to convert varchar to array in Presto Athena

Ты загрузил в Athena колонку с кучей JSON-ов в виде текста. Хочешь достать оттуда `skuid`, а вместо этого получаешь головную боль и ошибку `Unknown type: array`

Ты загрузил в Athena колонку с кучей JSON-ов в виде текста. Хочешь достать оттуда skuid, а вместо этого получаешь головную боль и ошибку Unknown type: array. Знакомо. Кажется, что CAST(col AS ARRAY) должен сработать, но он не срабатывает. Всё потому, что для движка это не массив, а просто строка — VARCHAR.

Именно такую строку ты видишь в своих данных. Даже если она выглядит как массив объектов, для SQL-движка это просто текст, который нужно сначала распарсить.

Почему CAST не работает

Потому что CAST меняет тип данных, но не парсит содержимое. Ты пытаешься сказать движку: «поверь мне, это массив», а он отвечает: «нет, это varchar, и я не вижу в нём запятых между элементами как в настоящем SQL-массиве». Он ожидает формат вроде ['a','b','c'], а у тебя — JSON.

Нужен правильный инструмент — функция JSON_PARSE. Она превратит твою строку в структурированный JSON, с которым уже можно работать.

Как разобрать JSON-массив

Вот рабочий подход, разбитый на шаги.

Сначала парсим строку в настоящий JSON. Без этого шага — никуда.

SELECT JSON_PARSE(col) AS json_array
FROM my_table

Теперь у тебя не строка, а массив. Его можно развернуть функцией UNNEST и обратиться к полям через JSON-оператор.

Полный запрос будет выглядеть так:

SELECT
  item['skuId'] AS sku_id
FROM
  my_table
CROSS JOIN
  UNNEST(JSON_PARSE(col)) AS t(item)

Что здесь происходит? JSON_PARSE(col) создаёт массив. UNNEST разворачивает этот массив в набор строк, где каждая строка — один элемент массива (в нашем случае — JSON-объект). А через item['skuId'] мы достаём нужное поле из каждого объекта.

Если в исходной строке где-то закралась невалидная JSON-структура — запрос упадёт. Поэтому иногда полезно обернуть JSON_PARSE в TRY, чтобы сломавшиеся строки превращались в NULL и не останавливали весь процесс.

CROSS JOIN UNNEST(TRY(JSON_PARSE(col))) AS t(item)

Итог

Порядок действий всегда один: строка → JSON_PARSE → UNNEST → обращение к полю. Запомни эту цепочку. Никакой прямой CAST из VARCHAR в ARRAY не сработает, потому что движку нужно явно дать команду интерпретировать текст как JSON.

Дальше можно усложнять: фильтровать по полям внутри JSON, агрегировать, присоединять к другим таблицам. Но основа — вот эти два оператора. Без них никуда.