/home/by-natures/dev*

データ界隈で働くエンジニアとしての技術的なメモと、たまに普通の日記。

2023/05/09 DuckDB のための AWS Lambda での文字コード変換

前回話した DuckDB の文字コード問題ですが、やはり UTF-8 しか想定されていないようです(DuckDB Foundation の方からリプを貰えました)。DuckDB は S3 や HTTP(S) などの外部データを直接読み込むことができる便利な機能がありますが、処理したいファイルの文字コードが UTF-8 以外だと DuckDB 以外のツールで変換する必要があります。

AWS Lambda でファイル取得&文字コード変換

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 を読み込めるようにします:

qiita.com

ワークフローまで考えたい

以前読んだ Medium の記事では、dbt を使う際に Astronomer や Google Cloud Composer を使っているものがありましたが、今回の私の簡単な例だけでもワークフロー管理まで考えると色々と疑問が出てきました:

  • AWS における dbt + Lambda ワークフロー管理(Glue?)
  • DuckDB の本番環境をどこで動かすか
  • アドホック分析環境をどこに用意するか?S3上にデータが揃うので Athena でもいいし、SnowPipe で Snowflake に流してもいい?

DuckDB はクラスタを必要としないデータ処理を行えることが強みなので、Snowflake を出してしまうと最初から Snowflake+dbt で良いのではと思ってしまいますね… アドホック分析も各自のローカル環境で DuckDB を直接 S3 Parquet ファイルを参照させる形になるんでしょうか。