Edited at

Aurora ServerlessにAWS LambdaのPythonからData APIで色々やってみたのでメモ


これ is 何

東京リージョンのAurora ServerlessでData API(HTTPエンドポイント)が使えるようになったものの日本語の情報が少なくて苦労したのでメモ。


著者がPython苦手問題

AWS Lambdaのために必要に駆られて書き始めたばかりなのでコード的にイケてないところが多いと思います。

こうした方が良いとかあればぜひとも教えていただきたいです:bow:


LambdaのBoto3古い問題

Layersを使って解決

$ mkdir python

$ pip install -t ./python boto3
$ zip -r boto3-x.y.z.zip python

できたZIPをLayersに登録、LambdaからそのLayerを選択すればimport boto3がLayerのboto3を使用してくれます。


Lambdaが使うIAMに追加で与える必要のある権限


  • secretsmanager:GetSecretValue

  • rds-data:ExecuteStatement

  • rds-data:BeginTransaction ※

  • rds-data:CommitTransaction ※

  • rds-data:RollbackTransaction ※

※ トランザクションを使わない場合には不要


テーブル

CREATE TABLE `test` (

`id` bigint NOT NULL AUTO_INCREMENT PRIMARY KEY,
`str` varchar(255) NOT NULL,
`date` timestamp NOT NULL,
`val` int)


Pythonコード

※ 実際のコードから有用そうな部分を抜粋したのでこのままで動くわけじゃないので注意してください。

import boto3

def lambda_handler(event, context):
cluster_arn = 'arn:aws:rds:ap-northeast-1:xxxxxxxxxxxx:cluster:yyyyyyyyyyyy'
secret_arn = 'arn:aws:secretsmanager:ap-northeast-1:xxxxxxxxxxxx:secret:zzzzzzzzzzzz'

rds_data_client = boto3.client('rds-data')

try:
transaction = rds_data_client.begin_transaction(
resourceArn = cluster_arn,
secretArn = secret_arn,
database = 'dbname'
)

# ここらへんでdictに色々詰めてる感じ
# dict['date']にはUNIX時間(秒)が入ってると思ってください

rds_data_client.execute_statement(
resourceArn = cluster_arn,
secretArn = secret_arn,
database = 'dbname',
transactionId = transaction['transactionId'],
sql = 'insert into test(str, date, val) values (:str, from_unixtime(:date), :val);',
parameters = [
{'name': 'str', 'value': {'stringValue': dict['str']}},
{'name': 'date', 'value': {'longValue': dict['date']}},
{'name': 'val', 'value': {'longValue': dict['value']} if dict['val'] else {'isNull': True}},
]
)

rds_data_client.commit_transaction(
resourceArn = cluster_arn,
secretArn = secret_arn,
transactionId = transaction['transactionId']
)

except Exception:
rds_data_client.rollback_transaction(
resourceArn = cluster_arn,
secretArn = secret_arn,
transactionId = transaction['transactionId']
)