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')