はじめに
パーティションを含むデータをGlueでテーブル化した際、テーブル全体の定義変更が各パーティションへ反映されないという事象が起きた為、解決方法を含めて記事化します。
前提
処理のおおまかな全体像は下記の通りです。
・S3に月次でcsvファイルを追加し、Athenaを通してそれらを分析
・Glue crawlerによりスキーマ,パーティション等をGlue Data Catalogへ登録
課題
元csvに「値として含まれる区切り文字」により、列のずれが発生
⇒この事象は以下のように、①囲み文字の設定 および ②テーブル定義の書き換え で解消すると考えられますが、以下の対応でずれが解消しない 点が課題でした。
以下はデータおよび事象のイメージです。
①csvに囲み文字""を設定
"日付","番号","名称"
"2023/01/01","001","aaa"
"2023/01/03","002","bbb"
"2023/01/04","003","cc,c"
"2023/01/06","004","ddd"
※便宜上、「ccc」ではなく「cc,c」が正しいとします。
②Glue Data Catalogのテーブル定義において、quoteChar(囲み文字),separatorChar(区切り文字)を指定
quoteChar "
separatorChar ,
<目標とする形>
下記のように、区切り文字「,」を含む値「cc,c」を名称として定義したい。
日付 | 番号 | 名称 |
---|---|---|
2023/01/01 | 001 | aaa |
2023/01/03 | 002 | bbb |
2023/01/04 | 003 | cc,c |
2023/01/06 | 004 | ddd |
<実際>
上記のように囲み文字を設定の上、データカタログ上で囲み文字,区切り文字の設定を行ったが、値「cc,c」に含まれるカンマが区切り文字として認識されたままとなっている。
日付 | 番号 | 名称 |
---|---|---|
2023/01/01 | 001 | aaa |
2023/01/03 | 002 | bbb |
2023/01/04 | 003 | cc |
c | 2023/01/06 | 004 |
原因
結論としては、 「Glue Data Catalogのテーブル定義と、各パーティションの定義は別管理である」 ようです。
Glueではパーティション毎にもテーブル定義を持っており、Data Catalogから 全体のテーブル定義を書き換えただけでは、各パーティションが保有するテーブル定義は書き換わらない 模様です。
今回の場合、区切り文字や囲み文字の定義はテーブル全体の定義を変更していた為、パーティション内の定義は以前のまま、区切り文字や囲み文字の定義を行っていない状態だった、という事になります。
パーティションは明示的に設定していた訳ではありませんが、月次でS3にcsvを追加していた為に切り分けられていました。
解決
パーティションが個別に持つ定義を更新する手段は以下3点です。
手段3 が最も簡単な方法ですが、参考として1,2も記載します。
手段1:AWS CLIから UpdatePartition API を実行することでパーティションの設定を変更
CLIから各パーティションの設定のみを書き換える方法です。
詳細は以下の通りです。
UpdatePartition - AWS Glue
update-partition — AWS CLI 2.6.4 Command Reference
手段2:Athena からパーティションを再作成
Athena のクエリを利用し、パーティションを一度削除の上で、再作成する方法です。
詳細は以下の通りです。
ALTER TABLE DROP PARTITION(パーティション削除)
ALTER TABLE ADD PARTITION(パーティション追加)
手段3:クローラ実行時に、テーブルのメタデータで更新されるように設定
全てのパーティションがテーブルのメタデータで更新されるように設定します。
手順としては、以下のようにクローラ作成時に1点、チェックを入れるだけです。
②作成手順ステップ4「Set output and scheduling 」の詳細設定を開く
③「Update all new and existing partitions with metadata from the table」にチェックを入れる
これにより各パーティションは、クローラの実行毎に親テーブルからメタデータを継承するようになります。
分類、入力フォーマット、出力フォーマット、SerDe情報(囲み文字,区切り文字,エスケープ文字等の情報)、スキーマなど、親テーブルのプロパティが引き継がれます。
おわりに
以前はathenaクエリによる削除と再作成の手順を踏んでいましたが、パーティションが増えると手間も掛かってしまいます。クローラに対して親テーブルの継承設定を行うというのが最適解のようです。
また、パーティションが設定されていない場合は、csvへの囲み文字の設定と、glueデータカタログにおけるテーブル定義の書き換えのみで問題なく対応が可能です。
ご覧いただきありがとうございました。