Загрузить поле массива в файле данных csv в таблицу Athena - PullRequest
0 голосов
/ 25 июня 2018

Это пример строки во входном файле данных с двумя полями - dept и names

dept,names
Mathematics,[foo,bar,alice,bob]

Здесь 'name' - это массив строк, и я хочу загрузить его как массив строкой Athena.

Есть предложения?

1 Ответ

0 голосов
/ 06 июня 2019

Чтобы иметь действительный файл CSV, убедитесь, что вы помещаете кавычки вокруг массива:

Mathematics,"[foo,bar,alice,bob]"

Если вы можете удалить «[» и «]», приведенное ниже решение станет еще проще, и вы можете просто разделить без регулярного выражения.

Better: Mathematics,"foo,bar,alice,bob"

Сначала создайте простую таблицу из CSV, содержащую только строки:

CREATE EXTERNAL TABLE IF NOT EXISTS test.mydataset (
  `dept` string,
  `names` string
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde'
WITH SERDEPROPERTIES (
  'serialization.format' = ',',
  'field.delim' = ',',
  'quoteChar' = '"',
  "separatorChar" = ',',
  'collection.delim' = ',',
  'mapkey.delim' = ':'
) LOCATION 's3://<your location>'
TBLPROPERTIES ('has_encrypted_data'='false')

Затем создайте представление, которое использует регулярное выражение для удаления символов «[» и «]», а затем разбивает остальное на «,» в массив.

CREATE OR REPLACE VIEW mydataview AS
SELECT  dept, 
        split(regexp_extract(names, '^\[(.*)\]$', 1), ',') as names
FROM mydataset 

Тогда используйте представление для ваших запросов. Я не уверен на 100%, так как я провел всего лишь 12 часов, используя Афину.

-

Обратите внимание, что для использования кавычек вам нужно использовать OpenCSVSerde, «lazyserde» не будет работать, поскольку он поддерживает кавычки. lazyserde поддерживает внутренние массивы, но вы не можете использовать ',' в качестве разделителя в этом случае. Если вы хотите попробовать это, ваши данные будут выглядеть так:

Better: Mathematics,foo|bar|alice|bob

В этом случае это МОЖЕТ работать напрямую:

CREATE EXTERNAL TABLE IF NOT EXISTS test.mydataset (
      `dept` string,
      `names` array<string>
    )
    ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde'
    WITH SERDEPROPERTIES (
      'serialization.format' = ',',
      'field.delim' = ',',
      'quoteChar' = '"',
      "separatorChar" = ',',
      'collection.delim' = '|',
      'mapkey.delim' = ':'
    ) LOCATION 's3://<your location>'
    TBLPROPERTIES ('has_encrypted_data'='false')

Обратите внимание, как collection.delim = '|', который должен преобразовывать ваше поле непосредственно в массив.

Извините, у меня нет времени, чтобы проверить это, я буду рад обновить мой ответ, если вы сможете подтвердить, что работает. Надеюсь, вы начали.

...