Как создать таблицу в AWS Athena из нескольких CSV по именам столбцов, а не по порядку столбцов - PullRequest
0 голосов
/ 16 мая 2018

Я хочу создать таблицу в AWS Athena из нескольких файлов CSV, хранящихся в S3.

У CSV есть строка заголовка с именами столбцов.Моя проблема в том, что в каждом CSV столбцы расположены в разном порядке, и я хочу получить столбцы по их именам.

Когда я пробую обычный CREATE TABLE в Афине, я получаю первые два столбца.

CREATE EXTERNAL TABLE `test`(
  `id` string, 
  `name` string)
ROW FORMAT SERDE 
  'org.apache.hadoop.hive.serde2.OpenCSVSerde' 
WITH SERDEPROPERTIES ( 
  'escapeChar'='\\', 
  'quoteChar'='\"', 
  'separatorChar'=',') 
STORED AS INPUTFORMAT 
  'org.apache.hadoop.mapred.TextInputFormat' 
OUTPUTFORMAT 
  'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION
  's3://...'
TBLPROPERTIES (
  'has_encrypted_data'='false')

вот пример:

csv 1:

+----+-------+-------+---------+
| id | name  | price | comment |
+----+-------+-------+---------+
|  1 | shirt |   123 | abc     |
|  2 | shoes |   222 | ddd     |
+----+-------+-------+---------+

csv 2:

+----+------+-------+-------+---------+
| id | size | price | color |  name   |
+----+------+-------+-------+---------+
|  5 | L    |   100 | red   | shirt   |
|  6 | S    |    55 | white | t-shirt |
+----+------+-------+-------+---------+

Таблица, которую я хочу:

+----+---------+
| id |  name   |
+----+---------+
|  1 | shirt   |
|  2 | shoes   |
|  5 | shirt   |
|  6 | t-shirt |
+----+---------+

Таблица, которую я получаю:

+----+-------+
| id | name  |
+----+-------+
|  1 | shirt |
|  2 | shoes |
|  5 | L     |
|  6 | S     |
+----+-------+

Спасибо

Ответы [ 4 ]

0 голосов
/ 08 января 2019

IMO, это довольно странно, что у Glue Crawler нет настройки для выбора имен столбцов и использования их для определения схемы таблицы. Мы столкнулись с этой проблемой (изменение схемы в той же папке в S3), и вот как мы ее решили.

Примечание - приведенное ниже решение работает, если вы можете сопоставить схему (порядок заголовков) с конкретными путями S3.

Исходные данные

У нас есть четыре файла. a.csv и b.csv используют одну и ту же схему, тогда как c.csv и d.csv имеют разные схемы.

$ cat a.csv
a,b
1,2
3,4
$ cat b.csv
a,b
5,6
3,4
$ cat c.csv
a,b,c
1,2,3
4,5,6
$ cat d.csv
a,c,d,x
6,7,8,9
1,2,3,4

Они сохраняются в S3:

$ aws s3 ls s3://example-s3-bucket/
2019-01-04 09:47:42         12 a.csv
2019-01-04 09:49:49         12 b.csv
2019-01-04 09:49:53         18 c.csv
2019-01-04 09:49:56         24 d.csv

Создать одну таблицу на схему

Создайте одну таблицу на схему, просто передав в нее одно и то же местоположение S3.

Обратите внимание, что для краткости я опускаю определения разделителя и разделителя полей.

create external table athena_testing_ab (
  a int,
  b int
)
LOCATION 's3://example-s3-bucket/'
;

create external table athena_testing_c (
  a int,
  b int,
  c int
)
LOCATION 's3://example-s3-bucket/'
;

create external table athena_testing_d (
  a int,
  c int,
  d int,
  x int
)
LOCATION 's3://example-s3-bucket/'
;

Запрос всех таблиц с использованием UNION s

Теперь мы запрашиваем эти 3 таблицы и UNION все вместе, фильтруя соответствующие пути S3 для каждой таблицы.

Возможно, вы захотите использовать синтаксический анализ регулярных выражений или подстрок, чтобы более элегантно фильтровать $PATH, особенно если в вашем ведре сотни или тысячи файлов.

select
  a,
  b,
  null as c,
  null as d,
  null as x
from
  athena_testing_ab
where "$PATH" in  ('s3://example-s3-bucket/a.csv', 's3://example-s3-bucket/b.csv')

union all

select
  a,
  b,
  c,
  null as d,
  null as x
from
  athena_testing_c
where "$PATH" in  ('s3://example-s3-bucket/c.csv')

union all

select
  a,
  null as b,
  c,
  d,
  x
from
  athena_testing_d
where "$PATH" in  ('s3://example-s3-bucket/d.csv')
0 голосов
/ 20 мая 2018

Поместите файлы в разные папки и используйте Glue Crawler для создания хранилища данных.

0 голосов
/ 20 мая 2018

Используйте клеевые гусеницы.Это будет полезно.

0 голосов
/ 17 мая 2018

Я бы пошел с двумя разными таблицами для разных CSV (вам нужно будет хранить ваши CSV в разных папках).

В конце концов, чтобы получить идентификатор, структуру имен для обоих CSV, я бы пошел с VIEW, чтобы объединить необходимые столбцы из разных таблиц.

...