特殊な区切り文字のファイルを Athena で S3 Tables に取り込む
はじめに
こんにちは!エノカワです。
今回は、特殊な区切り文字(0x16)を使用したファイルを Athena で S3 Tables に取り込む方法について検証した内容をご紹介します。
検証の背景
データ分析やETL処理において、特殊な区切り文字を使用したファイルを扱う必要がある場合があります。
今回の検証では、0x16(SYN)を区切り文字として使用したファイルを、Athena と S3 Tables を使用して取り込む方法を検証しました。
Glue などのETLサービスを使用せずに、Athena のクエリ機能のみで S3 Tables にデータを取り込むことが今回のポイントです。
0x16(SYN)は、Synchronous Idle(同期アイドル)を表す制御文字で、データ通信において同期を取るために使用される特殊な文字です。
検証環境の準備
サンプルファイルの作成
まず、検証用のサンプルファイルを作成します。
以下の Python スクリプトを使用して、0x16を区切り文字としたファイルを生成します。
なお、このファイルは厳密にはCSV(Comma-Separated Values)ではありませんが、便宜的に拡張子を.csv
としています。
import csv
# サンプルデータの準備
data = [
['ID', '名前', '年齢', '部署', '入社日'],
['1', '山田太郎', '30', '営業部', '2020-04-01'],
['2', '鈴木花子', '25', '人事部', '2021-07-01'],
['3', '佐藤次郎', '35', '技術部', '2019-10-01'],
['4', '田中一郎', '28', '営業部', '2022-01-01'],
['5', '伊藤美咲', '32', '技術部', '2018-04-01']
]
# 0x16を区切り文字としてファイルを作成
with open('sample_data.csv', 'w', encoding='utf-8') as f:
writer = csv.writer(f, delimiter=chr(0x16))
writer.writerows(data)
print("サンプルファイルを作成しました: sample_data.csv")
以下はサンプルファイルをエディタで開いた画面キャプチャです。
区切り文字がSYN(0x16)として赤文字で表示されていることが確認できます。
S3 Tables 作成
まずは S3 Tables を作成します。
下記の記事で手順が紹介されているので、こちらを参考に作業を進めます。
1. テーブルバケットの作成
S3 Tables を使用するために、まずテーブルバケットを作成します。
マネジメントコンソールから S3 の画面を開き、[テーブルバケット] を選択します。
[テーブルバケットを作成] を選択します。
テーブルバケット名を入力し、[AWS 分析サービスとの統合 の [統合を有効にする] にチェックを入れます。
テーブルバケットが正常に作成されました。
作成されたテーブルバケットを選択します。
2. 名前空間の作成
次に、データを格納するための名前空間を作成します。
[Athena でテーブルを作成] を選択します。
名前空間を入力して、[名前空間を作成] を選択します。
名前空間が正常に作成されました。
[Athena でテーブルを作成] を選択します。
データベース欄が作成した名前空間になっていることを確認します。
3. テーブルの作成
S3 Tables のテーブルを作成します。
以下のSQLを実行して、S3 Tables のテーブルを作成します。
CREATE TABLE `cm_enokawa_s3_namespace`.employees (
id string,
name string,
age string,
department string,
hire_date string
)
PARTITIONED BY (department)
TBLPROPERTIES ('table_type' = 'iceberg')
SQLを入力して、[実行] を選択します。
クエリが成功しました。
作成したテーブルスキーマが確認できます。
データの取り込み
1. ファイルアップロード
作成したサンプルファイルを汎用バケットにアップロードします。
2. 外部テーブルの作成
特殊な区切り文字のファイルを扱うために、まず外部テーブルを作成します。
CREATE EXTERNAL TABLE default.temp_employees
(
id string,
name string,
age string,
department string,
hire_date string
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\u0016'
LOCATION 's3://cm-enokawa-s3-table-source/'
TBLPROPERTIES ('skip.header.line.count' = '1');
データベースをdefault
に変更します。
テーブル作成DDLを実行します。
SELECT
を実行し、サンプルデータが参照できることを確認します。
3. データの取り込み
外部テーブルから S3 Tables のテーブルにデータを取り込みます。
以下のSQLを実行します。
INSERT INTO cm_enokawa_s3_namespace.employees
SELECT * FROM default.temp_employees;
すると、エラーが発生しました。
エラーメッセージ:
SCHEMA_NOT_FOUND: line 2:15: Schema 'default' does not exist. You may need to manually clean the data from the table. Athena will not delete data in your account.
S3 Tables と外部テーブルは異なるカタログに属しているため、データの移動ができません。
Athena では、データソースを管理するためにカタログという概念があります。
S3 Tables は独自のカタログ(s3tablescatalog
)を使用し、外部テーブルは通常の AWS Data Catalog(awsdatacatalog
)を使用します。
異なるカタログ間でデータを移動する場合は、カタログ名を明示的に指定する必要があります。
カタログを指定して、以下のSQLを実行します。
INSERT INTO cm_enokawa_s3_namespace.employees
SELECT * FROM awsdatacatalog.default.temp_employees;
クエリが成功しました!
SELECT
を実行し、データが取り込まれていることを確認します。
先ほどは S3 Tables のカタログを選択した状態で実行したのでSQLが成功しましたが、default
データベースを選択した場合は失敗します。
以下のSQLのように S3 Tables 側もカタログを明示的に指定することで回避できます。
INSERT INTO "s3tablescatalog/cm-enokawa-s3-table-bucket".cm_enokawa_s3_namespace.employees
SELECT * FROM awsdatacatalog.default.temp_employees;
まとめ
以上、特殊な区切り文字のファイルを Athena で S3 Tables に取り込む方法の紹介でした。
今回の検証では、特殊な区切り文字を持つファイルを Glue を使わずに Athena で外部テーブルを経由して S3 Tables に取り込みました。
外部テーブルを一時的なステージングエリアとして活用することで、データパイプラインをシンプルに保つことができます。
技術的な勘所としては、INSERT
文を実行する際に異なるデータカタログ(awsdatacatalog
と s3tablescatalog
)を明示的に指定する必要がありました。
この点を押さえておけば、一見複雑に見えるデータ取り込みもスムーズに実行できます。
特殊な区切り文字を持つファイルの扱いに困った際は、ぜひこの方法を試してみてください!
参考URL
- AWS公式ドキュメントのチュートリアルでS3Tablesに入門してみた | DevelopersIO
- AWS Lakeformationを使ってData Lakeを構成してみた | DevelopersIO
- S3 TablesのAWS分析サービスとの統合がアップデートされたので、アップデートしてみた | DevelopersIO
- 「AWS Lake Formationへの恐怖心はこれで解消!肝の3つを理解する」というタイトルで社内でお話したので資料公開します | DevelopersIO
- Amazon S3 Tables で Iceberg 機能と LakeFormation統合機能を試す #AWS - Qiita
- AWS Lake Formationを有効にした時の既存リソース(Glue,S3)へのアクセスについて整理してみる | DevelopersIO
- Amazon S3 Tables - AWS
- Amazon Athena - AWS