[新機能] Amazon Athena UNLOADコマンドによるCSV、Parquet、Avro、ORC、JSON出力をサポートしました!
データアナリティクス事業本部コンサルティングチームの石川です。先日、Amazon Athenaが、UNLOADコマンドをサポートしました。SELECTクエリの結果をCSV、Parquet、Avro、ORC、JSONフォーマットでS3出力できるようになりました。本日は、UNLOADコマンドを実際に試してみます。
UNLOADコマンド
UNLOADコマンドの構文は、以下のとおりです。
UNLOAD (SELECT col_name[, ...] FROM old_table) TO 's3://my_athena_data_location/my_folder/' WITH ( property_name = 'expression' [, ...] )
WITH句の中にフォーマット(format)、区切り文字(field_delimiter)、圧縮タイプ(compression)、パーティション(partitioned_by)を指定します。
フォーマット(format)
format = 'file_format
'
以下の出力フォーマットをサポートしています。
- AVRO
- PARQUET
- ORC
- JSON
- TEXTFILE
区切り文字(field_delimiter)
field_delimiter = 'delimiter
'
フォーマット(format)が、TEXTFILE
の場合は、区切り文字(field_delimiter)を指定できます。デフォルトは0x01
となります。
圧縮タイプ(compression)
compression = 'compression_format
'
- ORC:zlib(デフォルト)、lz4、snappy、zstd
- Parquet:gzip(デフォルト)、snappy
- 上記以外のフォーマット:gzip(デフォルト)
パーティション(partitioned_by)
partitioned_by = ARRAY[ col_name
[,…] ]
パーティション(partitioned_by)指定したい場合は、パーティションするキーを配列で指定します。
WITH (format = 'TEXTFILE', partitioned_by = ARRAY['key1', 'key2'])
使用例
Avro出力
UNLOAD (SELECT * FROM "ssbgzdb"."customer") TO 's3://cm-temp-jp/customer/avro/' WITH (format = 'AVRO')
Parquet出力
UNLOAD (SELECT * FROM "ssbgzdb"."customer") TO 's3://cm-temp-jp/customer/parquet/' WITH (format = 'PARQUET',compression = 'SNAPPY')
ORC出力
UNLOAD (SELECT * FROM "ssbgzdb"."customer") TO 's3://cm-temp-jp/customer/orc/' WITH (format = 'ORC',compression = 'zstd')
JSON出力
UNLOAD (SELECT * FROM "ssbgzdb"."customer") TO 's3://cm-temp-jp/customer/json/' WITH (format = 'JSON')
TEXTFILE出力
デフォルトの区切り文字(field_delimiter)となります。ファイルのヘッダは、出力されません。
UNLOAD (SELECT * FROM "ssbgzdb"."customer") TO 's3://cm-temp-jp/customer/textfile/' WITH (format = 'TEXTFILE')
CSV出力したい場合は、field_delimiter = ','
、TSV出力したい場合は、field_delimiter = '\t'
を追加します。下記の例は、CSV出力の例です。
UNLOAD (SELECT * FROM "ssbgzdb"."customer") TO 's3://cm-temp-jp/customer/csv/' WITH (format = 'TEXTFILE',field_delimiter = ',')
TEXTFILE出力のパーティション指定
パーティション指定すると、指定したS3パスの直下に、カラム名ありパーティション形式のフォルダが作成され、フォルダの下にファイルが出力されます。
UNLOAD (SELECT * FROM "ssbgzdb"."customer") TO 's3://cm-temp-jp/customer/textfile_partitioned/' WITH (format = 'TEXTFILE', partitioned_by = ARRAY['c_mktsegment'])
注意点
エンジンバージョンは、Version2のみ
今日現在、デフォルトのエンジンバージョンは、Version2なので実質的にあまり問題にならないはずですが、念の為ご注意ください。
出力パスにS3オブジェクトが存在するとエラーになる
すでに出力パスにS3オブジェクトが存在するとエラーになります。データを洗い替えたい場合は、出力パスのS3オブジェクトを事前に削除する必要があります。
最大パーティション数は100以内
パーティションの数が100を超えると、エラーになります。そのため、パーティション数が100を超えるユースケースではパーティション指定(partitioned_by)の利用を避けたほうが良いでしょう。
パーティション指定できるカラムは最後のカラムのみ
パーティション指定できるカラムは最後のカラムのみです。
そのため、最後のカラム以外をパーティションキーに指定したい場合は、SELECTに指定するカラム名の最後にパーティションキーを指定することで回避することができます。
UNLOAD (SELECT c_custkey, c_name, c_address, c_region FROM "ssbgzdb"."customer") TO 's3://cm-temp-jp/customer/textfile_partitioned_xxx/' WITH (format = 'TEXTFILE', partitioned_by = ARRAY['c_region'])
Athenaは、障害が発生した場合、孤立したデータの削除をしません。そのため、UNLOADコマンドに指定するS3の出力パスはテンポラリなワーキングディレクトリを指定して、Athenaの実行が成功した後にターゲットディレクトリの削除とコピーするように実装したほうが良いのではないかと考えられます。
まとめ
UNLOADコマンドで、SELECTクエリの結果をCSV、Parquet、Avro、ORC、JSONフォーマットでS3出力できるようになりました。つまり、Athenaのようなサーバレスな仕組みを用いてSQLのみでELT (Extract、Load、Transform)ができるようになりました。今回のアップデートを利用することで、素早くコスト効率の良いAthenaでデータ加工ができるようになります。UNLOADコマンドによって出力されるファイルは、ファイル数が多い傾向がありますが、その点が問題なければ有効な選択肢になるはずです。