#amazon-athena #presto #trino
Вопрос:
У меня есть база данных AWS Athena (parquet), которая в консоли Athena возвращает:
.. из следующего запроса:
SELECT id,
TYPEOF(organisations) as type,
cardinality(organisations) as len,
organisations
FROM mydb.tbl;
Чтение полной таблицы удаленно в Python (с помощью awswrangler) не удается, потому organisations
что это массив (иногда нулевой длины). Я пытался преобразовать organisaions
поле в строковое представление массива (или эквивалентный json), но ничего из того, что я пробовал до сих пор, не работает. Любые сладости очень ценятся.
Ответ №1:
Если вы не заботитесь о сохранении organization
charoffset
имен полей и, вы можете преобразовать массив в JSON
, а затем отформатировать его, как varchar
с json_format
:
WITH t(organizations) AS (
VALUES
ARRAY[ROW('x', 1), ROW('y', 2)],
ARRAY[ROW('a', 3), ROW('b', 4)],
ARRAY[]
)
SELECT json_format(CAST(organizations AS JSON))
FROM t
=>
_col0
-------------------
[["x",1],["y",2]]
[["a",3],["b",4]]
[]
Комментарии:
1. Да
json_format(CAST(organizations AS JSON))
, это работает на меня! Спасибо, Мартин 🙂2. Теперь я понимаю, что вместо того, чтобы потерять ключи как ключи (т. Е., но сохраненные в массиве), я потерял их полностью. Например
[{type=World City, name=Mumbai, Maharashtra, India, country=IN, adm1=IN16, adm2=70184, latitude=18.975, longitude=72.8258}]
[["World City","Mumbai, Maharashtra, India","IN","IN16","70184",18.975,72.8258]]
, становится . Есть идеи, как сохранить ключи в массивах?3. Значения будут упорядочены в зависимости от того, как они отображаются в объектах СТРОК, поэтому вы можете предоставить клиенту возможность их получения (например, путем проверки типа поля организации). Существует давняя проблема, связанная с изменением поведения приведения строки->json для получения того, что вы ищете, но это сложно, потому что это изменение, несовместимое с обратной связью: > github.com/trinodb/trino/issues/3536 . Кроме того, может пройти много времени, прежде чем он попадет в Афину.
4. Хорошо, еще раз спасибо, Мартин. Интересно, есть ли тогда другой метод, который можно использовать. Кажется довольно тривиальной проблемой стать блокировщиком проектов!
Ответ №2:
Если элементы вашего массива можно привести к varchar
, вы можете преобразовать массив в строку с помощью array_join
функции, см. Документы здесь
https://prestodb.io/docs/current/functions/array.html
Например:
WITH t(organizations) AS (
VALUES
ARRAY[1,2,3,4,5],
ARRAY[]
)
SELECT array_join(organizations, ',')
FROM t
Если ваши массивы содержат более сложные элементы, вы можете сначала использовать transform
функцию, чтобы преобразовать их в varchar «на заказ» и передать это в array_join
функцию, например:
WITH t(organisations) AS (
VALUES
ARRAY[cast(ROW('Police Scotland', 6) as ROW(organisation varchar, charoffset integer))],
ARRAY[]
)
SELECT '{' || array_join(transform(organisations, x -> '{organisation='||x.organisation||',charoffset='||cast(x.charoffset as varchar)||'}'),',') || '}'
FROM t
Комментарии:
1. Интересно, но очень неясно, как это должно работать, и в документации нет примеров. Тестирование на моем поле массива
array_join(organisations, delimiter = ";", null_replacement = "")
возвращаетSYNTAX_ERROR: line 9:32: Column 'delimiter' cannot be resolved
результаты . Требуется ли для этой функции сопоставление?2.
varchar
указываются в одинарных кавычках. Но действительно, приведенное выше решение будет работать только тогда , когда элементы массива могут быть приведеныvarchar
, что, похоже, не относится к вашему случаю. Я отредактировал ответ.