見出し画像

【AWS】 Athena × S3 バージョニングされた過去データをクエリしてみた|1日1ハンズオン Day 37

こんにちは、ぽめら です。
本記事は1日1ハンズオン企画、第37回です!
今回も引き続き Amazon Athena に触れていきます。

テーマは「Athena × S3 バージョニング」。S3で有効化したバージョニング付きデータを、Athenaでどう扱えるかを試してみます📁



1.はじめに

前回(Day36)は、Athena の基本動作を学ぶため「S3上のCSVデータをSQLで直接クエリする」をやってみました。Athenaはサーバレスでデータベースを立てずにSQL分析できるという特長を学んだ回です✍️

今回はそこに “履歴” の概念を足していきます。
S3では「バージョニング」を有効にすることで、同一ファイルの過去バージョンを保持できます。この仕組みを活かして、Athenaで過去データの比較・時系列分析 に応用してみるのが今回の趣旨👀

というわけで、レッツハンズオン!


2.Athena × S3 バージョニングやってみた

今回の主な流れは下記の通りです。

  • S3バケットを作成(バージョニング有効化)

  • データのバージョンを作成

  • Athenaテーブルを作成

  • バージョンデータをクエリ

  • クリーンアップ


2-1.S3バケットを作成してバージョニングを有効化する

まずは検証用バケットを作成します。
コマンドはこれまでどおり aws s3api create-bucket です。

aws s3api create-bucket \
  --bucket pomera-handson-day37 \
  --region ap-northeast-1 \
  --create-bucket-configuration LocationConstraint=ap-northeast-1

続いて、バージョニングを有効化。

aws s3api put-bucket-versioning \
  --bucket pomera-handson-day37 \
  --versioning-configuration Status=Enabled

※ S3 のバージョン管理有効化については過去回も参照

確認👇

aws s3api get-bucket-versioning --bucket pomera-handson-day37

出力例:

{
  "Status": "Enabled"
}

👉 Status が Enabled ならOKです🙆


2-2.S3にデータをアップロード&更新してバージョンを作成

今回は同じファイル名を使って、内容を2回更新します。

echo "id,product,price" > versioned.csv
echo "1,apple,120" >> versioned.csv
aws s3 cp versioned.csv s3://pomera-handson-day37/data/

次に内容を更新して再アップロード。

echo "id,product,price" > versioned.csv
echo "1,apple,120" > versioned.csv
echo "2,banana,150" >> versioned.csv
echo "3,orange,200" >> versioned.csv
aws s3 cp versioned.csv s3://pomera-handson-day37/data/

バージョンを確認します👇

aws s3api list-object-versions --bucket pomera-handson-day37

出力例:
※ 長いのでエンターでスクロールが必要。抜ける時は「q」

{
  "Versions": [
    {
      "Key": "data/versioned.csv",
      "VersionId": "abc123",
      "IsLatest": false
    },
    {
      "Key": "data/versioned.csv",
      "VersionId": "xyz456",
      "IsLatest": true
    }
  ]
}

👉 2つのVersionIdがあることを確認できれば成功です!


2-3.Athenaでテーブルを作成して最新データをクエリ

Athenaクエリエディタを開き、データベースを作成します。

CREATE DATABASE IF NOT EXISTS pomera_day37;

次にテーブルを作成します。

CREATE EXTERNAL TABLE IF NOT EXISTS pomera_day37.versioned_data (
  id INT,
  product STRING,
  price INT
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde'
WITH SERDEPROPERTIES (
  "separatorChar" = ",",
  "quoteChar" = "\""
)
LOCATION 's3://pomera-handson-day37/data/'
TBLPROPERTIES ("skip.header.line.count"="1");

確認👇

SELECT * FROM pomera_day37.versioned_data;

出力例:

2回目に保存したapple, banana, orangeの3つが出力される

👉 最新バージョンで書き込んでいたが反映されています。


2-4.過去バージョンのファイルをクエリする

Athenaでは直接「VersionId」を指定してクエリすることはできませんが、
S3オブジェクトを一時的に別パスにコピーすることで過去バージョンも参照できます。

古いVersionId(1回目) データをDLして再配置してみる。
※ --version-id の引数に、 aws s3api list-object-versions --bucket pomera-handson-day37 で確認した過去バージョンの"VersionId"を指定する。

例:(コンソール)
下記例は"pomera-handson-day37"(バケット名)の"data/versioned.csv"から、version-id が"abc123"のバージョンを取得して、"old_versioned.csv"の名前でS3に配置している。

# 過去バージョンのVersionIdを確認
aws s3api list-object-versions --bucket pomera-handson-day37

# VersionIdを指定して過去バージョンを取得
aws s3api get-object \
  --bucket pomera-handson-day37 \
  --key data/versioned.csv \
  --version-id abc123 \
  old_versioned.csv

それを再アップロード👇(コンソール)

# S3にアップロード
aws s3 cp old_versioned.csv s3://pomera-handson-day37/data/old/

Athenaで別テーブルとして登録してみます。(Ahtenaのクエリエディタ)

CREATE EXTERNAL TABLE IF NOT EXISTS pomera_day37.old_data (
  id INT,
  product STRING,
  price INT
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde'
WITH SERDEPROPERTIES (
  "separatorChar" = ",",
  "quoteChar" = "\""
)
LOCATION 's3://pomera-handson-day37/data/old/'
TBLPROPERTIES ("skip.header.line.count"="1");
左側の「テーブル」欄にold_dataとversioned_dataの2テーブルが作成されていることを確認

クエリしてみる👇(Athenaのクエリエディタ)

SELECT * FROM pomera_day37.old_data;

出力例:

1列だけ出力されていることを確認

👉 古いバージョン(初期データ)をAthena経由で参照できました!

今回やりたかったバージョン別のデータ確認は以上です。


2-5.クリーンアップ

最後に検証用のリソースを削除します。

👇Athena クエリエディタ

# Athena上のDB削除
DROP DATABASE pomera_day37 CASCADE;

👇 AWS CLI

# オブジェクト削除
aws s3 rm s3://pomera-handson-day37 --recursive

# バージョン付きオブジェクト削除
aws s3api delete-objects \
  --bucket pomera-handson-day37 \
  --delete "$(aws s3api list-object-versions \
    --bucket pomera-handson-day37 \
    --output json \
    --query='{Objects: Versions[].{Key:Key,VersionId:VersionId}}')"

aws s3api delete-objects \
  --bucket pomera-handson-day37 \
  --delete "$(aws s3api list-object-versions \
    --bucket pomera-handson-day37 \
    --output json \
    --query='{Objects: DeleteMarkers[].{Key:Key,VersionId:VersionId}}')"

# バケット削除
aws s3api delete-bucket --bucket pomera-handson-day37 --region ap-northeast-1

3.まとめ

今回は、S3バージョニングとAthenaの組み合わせを試しました!

・バージョン管理有効化
👉 put-bucket-versioning

・過去バージョン確認
👉 list-object-versionsVersionIdで履歴確認

・過去データ参照
👉 get-object

Athena単体ではVersionIdを直接指定できない。しかし、S3のバージョン管理機能を活用することで履歴比較もできるようになる。ふむ、なるほど✍️

というわけで今日はここまで!
ではまた明日👋


4.参考リンク

・S3 バージョニングについて

・Athena テーブル定義の作成方法

・AWS CLI コマンドリファレンス (s3api)


いいなと思ったら応援しよう!