[小ネタ] Athena の UNION を使用して複数 S3 バケットの情報を同時にクエリしてみた

[小ネタ] Athena の UNION を使用して複数 S3 バケットの情報を同時にクエリしてみた

Clock Icon2025.04.24

現時点(2025/04/24)では、Athena でテーブルを作成する際に複数の S3 バケットを指定することはできません。
以下ドキュメントにあるように CREATE TABLE 文の LOCATION 句では、必ず 1 つの S3 バケットのみ指定する必要があります。

https://docs.aws.amazon.com/ja_jp/athena/latest/ug/tables-location-format.html

そのため、テーブル定義を行う際に、LOCATION 句に複数の S3 バケットを指定することやバケットを指定せずに全てのバケットを対象とするような設定はできません。

Athena から複数 S3 バケットを同時にクエリするためには、テーブルを S3 バケット毎に作成し、クエリ時に UNION を利用して結合する方法があります。
以下、その手順の紹介です。

S3 バケットにサンプルデータをアップロード

デフォルト設定で S3 バケットを2つ作成します。
スクリーンショット 2025-04-21 16.54.42

S3 バケットにアップロードするための CSV データを作成します。

sample1.csv
UserName,Place
Takahashi,Tokyo
Kimura,Fukuoka
Nakamura,Tokyo
Satou,Osaka
sample2.csv
UserName,Place
Tanaka,Kyoto
Matumoto,Nagasaki
sample3.csv
UserName,Place
Kojima,Nara
Murata,Fukui

S3 バケットに CSV をアップロードします。
以下画像のように S3 バケット sunagawa-test-bucket-1 に sample1.csv, sample2.csv を配置し、
sunagawa-test-bucket-2 に sample3.csv をアップロードした状態です。

  • sunagawa-test-bucket-1
    スクリーンショット 2025-04-24 15.15.57

  • sunagawa-test-bucket-2
    スクリーンショット 2025-04-24 15.18.23

Athena テーブル作成

Athena のクエリエディタの「作成」ボタンを選び、「S3 バケットデータ」を選択します。
スクリーンショット 2025-04-24 17.13.31

任意のテーブル名を指定します。
スクリーンショット 2025-04-24 17.17.10

データセットの場所として、先の項目で作成した1つ目の S3 バケットを指定します。
スクリーンショット 2025-04-24 17.17.58

ファイル形式を CSV とします。
スクリーンショット 2025-04-24 17.20.14

列の詳細にて、CSV ファイルのカラムをそれぞれ設定します。
スクリーンショット 2025-04-24 17.21.27

テーブルのプロパティにて skip.header.line.count を 1 に設定します。(これは CSV ファイルのヘッダー行を Athena テーブルに含めないようにする設定です。)
スクリーンショット 2025-04-24 17.22.28

上記設定ができたら、「テーブルを作成」を押下し、 Athena テーブルを作成します。
実際には、上記設定に応じて、以下のような CREATE TABLE 文が自動作成、実行され、Athena テーブルが作られます。

CREATE EXTERNAL TABLE IF NOT EXISTS `default`.`testtable1` (`UserName` string, `Place` string)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe'
WITH SERDEPROPERTIES ('field.delim' = ',')
STORED AS INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION 's3://sunagawa-test-bucket-1/'
TBLPROPERTIES (
  'classification' = 'csv',
  'skip.header.line.count' = '1'
);

コンソールを見ると、以下のように testtable1 が作成されていることがわかります。
スクリーンショット 2025-04-24 17.33.42

続いて、2つ目の S3 バケットをクエリするための Athena テーブル testtable2 を作成します。
先ほど作成された CREARTE TABLE 文を流用し、テーブル名の部分を testtable2 に変更、LOCATION 句 に指定する S3 バケットを sunagawa-test-bucket-2 に変更しています。それ以外は変わりません。

CREATE EXTERNAL TABLE IF NOT EXISTS `default`.`testtable2` (`UserName` string, `Place` string)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe'
WITH SERDEPROPERTIES ('field.delim' = ',')
STORED AS INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION 's3://sunagawa-test-bucket-2/'
TBLPROPERTIES (
  'classification' = 'csv',
  'skip.header.line.count' = '1'
);

上記をクエリエディタで実行すると、以下のように testtable2 が作成されました。これで準備 OK です。
スクリーンショット 2025-04-24 17.40.05

動作確認

動作確認をしていきます。
Athena では UNION 句を使用することで、複数テーブルをクエリすることが可能です。
具体的には以下のような形でクエリします。

SELECT * FROM testtable1 UNION ALL SELECT * FROM testtable2;

実行結果を見ると以下のように、S3 にアップロードされた sample1 から sample3 までの CSV ファイルの結果が取得できていることがわかります。これで複数バケットを同時にクエリすることができました。
スクリーンショット 2025-04-24 17.48.04

終わりに

今回は、Athena で複数 S3 バケットに対して同時にクエリできるか試してみました。
最初は CREATE TABLE 文のテーブル定義で、複数バケットを指定できるかとか色々試しましたが、ドキュメントにある通り、その使い方はサポートされていないことがわかりました。
複数バケットをクエリする際は、複数テーブルを作成して UNION を使用することが現実的な解決法になります。

今後、Athena テーブル作成時に複数のバケットが設定できるようになったら嬉しいですね。
本ブログがどなたかお役に立ちますと幸いです。

参考情報

https://docs.aws.amazon.com/ja_jp/athena/latest/ug/tables-location-format.html
https://docs.aws.amazon.com/ja_jp/athena/latest/ug/select.html

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.