#やりたいこと
・S3にunloadクエリをputするとLambdaで拾ってRedshiftに流すようなサーバレスな処理を作りたい
・Python3でやりたい。
#記事で割愛していること
- VPCの設定(ネットワーク的にLambdaとRedshiftが疎通していること)
- Lambdaの基本設定(VPCや、トリガーの設定)
#手順
Python3のインストール
Python3でやりたい。その辺にあったAmazon Linuxにて
sudo yum install python36
psycopg2の準備
以下のコマンドで、-t で指定した場所にpsycopg2が設置される。
pip-3.6 install psycopg2 -t ./
ソースコードの作成
vi lambda_function.py
接続⇒実行までの超最低限サンプル
import psycopg2
def lambda_handler(event, context):
try:
connection = psycopg2.connect(port=5439, host="(VPC内のRedshiftのホスト)", database="XXXX", user="XXXX",password="XXXX")
with connection.cursor() as cur:
cur.execute("※ unloadクエリ ");
return "test"
except Exception as e:
print(e)
raise e
デプロイパッケージの作成
解凍したらディレクトリは挟まず、直接 lambda_function.pyと、pipで取得したpsycopg2/のディレクトリが出てくるように圧縮
lambda_function.py
psycopg2/
ファイル名は任意。
作成したものをコードエントリタイプ「.ZIPファイルをアップロード」よりアップ。
すごい
デプロイパッケージでアップロードしたあとで、「コードをインラインで編集」が使える。
zipファイルと同期が取れれなくなるが開発にはとても便利。
やって分かった事
Lambdaのタイムアウトになっても、unloadクエリの実行が開始されていればunload自体はRedshift上で処理は続くようなので、5分以上掛かるクエリであってもこの仕組みだと問題なさそう。やった!
ただし、このあたりはコンテナが破棄されなければ、みたいな話かなとも予想される。
どのみちクリティカルな処理をやるつもりは無いので深追いせず。
#エラー変遷
Unable to import module 'lambda_function': No module named 'psycopq2'
今回使うパッケージ名は psycop"g"2 である...
コピペをすれば良い、というものではないというインターネットの罠。
Unable to import module 'lambda_function': No module named 'psycopg2._psycopg'
手元のWindows10のGit Bashで作業をしていたが、WindowsのGit Bashで pip install をすると
Windows用のパッケージとなってしまい、LinuxであるLambda上で動かないというのが原因だった。
このため、psycopg2のパッケージだけLinuxで用意するという手順を踏んでいる。
could not connect to server: Connection timed out
普通にPort指定を忘れていたため。
なお、psycopg2はデフォルトだとportは5432となり
Redshiftはデフォルトだとportは5439なので、Portの指定は必須な可能性が限りなく高い。
FATAL: password authentication failed for user "XXXX"
複雑なパスワードがPython上で上手くエスケープできなかったため。