前回話した DuckDB の文字コード問題ですが、やはり UTF-8 しか想定されていないようです(DuckDB Foundation の方からリプを貰えました)。DuckDB は S3 や HTTP(S) などの外部データを直接読み込むことができる便利な機能がありますが、処理したいファイルの文字コードが UTF-8 以外だと DuckDB 以外のツールで変換する必要があります。
Correct, it must be UTF8. I typically loop over the files with Python to covert to UTF8, then I can do all my other processing in DuckDB! I believe I used the chardet library.
— Alex Monahan (@__AlexMonahan__) May 2, 2023
AWS Lambda でファイル取得&文字コード変換
DuckDB で直接読み込むことは諦めて、自動化を見据えたユースケースとして AWS Lambda で文字コード変換とヘッダ処理だけ行いました。Pandas の read_csv
が直接 URL を引数に受け取れるのが強力でした。ここに文字コード sjis
を指定して、出力時に utf8
を指定することで文字コード変換をします。
import boto3 import pandas as pd from io import StringIO def lambda_handler(event, context): # Read the target data through 'read_csv function url = 'https://path/to/file' df = pd.read_csv(url, header=7, encoding='sjis') # Write the CSV data into a dataframe csv_buffer = StringIO() df.to_csv(csv_buffer, encoding='utf8', header=True, index=False) # Store the result into S3 s3_resource = boto3.resource('s3') s3_resource.Object('bucket-name', 'output-path.csv').put(Body=csv_buffer.getvalue()) return "OK"
Pandas を読み込むためのレイヤー追加
AWS Lambda のランタイムは Python 3.10 を選択しましたが、このランタイムには標準で Pandas が含まれていません。レイヤー追加して Pandas を読み込めるようにします:
ワークフローまで考えたい
以前読んだ Medium の記事では、dbt を使う際に Astronomer や Google Cloud Composer を使っているものがありましたが、今回の私の簡単な例だけでもワークフロー管理まで考えると色々と疑問が出てきました:
- AWS における dbt + Lambda ワークフロー管理(Glue?)
- DuckDB の本番環境をどこで動かすか
- アドホック分析環境をどこに用意するか?S3上にデータが揃うので Athena でもいいし、SnowPipe で Snowflake に流してもいい?
DuckDB はクラスタを必要としないデータ処理を行えることが強みなので、Snowflake を出してしまうと最初から Snowflake+dbt で良いのではと思ってしまいますね… アドホック分析も各自のローカル環境で DuckDB を直接 S3 Parquet ファイルを参照させる形になるんでしょうか。