Amazon AthenaでCSVに含まれていない情報をS3のフォルダ名から取得する場合に苦労したため、解決方法を紹介しておきます。
結論から言うと、partition分割を使い、フォルダ毎にpartitionとして読み込むことで、AthenaのSQLからフォルダ名を参照することできます。
S3上のCSVファイルをAthenaから読む際に問題が発生するケース
以下のようなケースでは、S3上のCSVファイルにはuser_idが存在しないため、そのままCSVのカラムをAthenaのテーブルとしてマッピングすることができません。
- S3上にCSV形式でユーザーの行動ログが入っている
- ユーザーごとにS3上でフォルダが分けられている
- CSVファイルにはユーザーIDが含まれておらず、ユーザーIDはS3のpathからしか分からない
行動ログCSV
| date | action |
|---|---|
| 2018-04-24 | view_page |
| 2018-04-25 | payment |
ログ保存場所(user_idが1の場合)
s3://user-action-logs/1/action.log
解決方法
このような場合は、Athenaのテーブルをuser_idごとにpartition分割し、それぞれのフォルダとパーティションとして読み込むことで、SQL上から参照できるようになります。
テーブルの作成
以下のように PARTITIONED BY に user_id を指定します。
CREATE EXTERNAL TABLE user_actions (
date timestamp,
action string
)
PARTITIONED BY (user_id int)
LOCATION 's3://user-action-logs/'
-- 以下メタデータ省略
partitionの追加
以下のクエリを実行し、特定ディレクトリ以下をpartitionとして追加します。 読み込みたいpath全てに対して実行する必要があります。
ALTER TABLE user_actions ADD PARTITION (user=1) location 's3://user-action-logs/1/'
SQLでの参照
partitonは通常のカラムと同様に参照することができます。
SELECT user_id, date, action FROM user_actions WHERE user_id = 1
まとめ
Amazon AthenaでCSVに含まれていない情報をS3のフォルダ名から取得したい場合、partition分割を使い、フォルダ毎にpartitionとして読み込むことで、AthenaのSQLからフォルダ名を参照することできます。