boto3 + DynamoDBでリストに要素を追加・削除
目標
dynamoDBに入っているリスト要素に対して、追加・削除を行う
環境
コード
import boto3 import decimal import json from boto3.dynamodb.conditions import Key, Attr # DB設定 dynamodb = boto3.resource('dynamodb') table = dynamodb.Table('table') # Helper class to convert a DynamoDB item to JSON. # AWSのドキュメントにあったもの。これがないとnumber <-> floatの変換周りでエラーになる class DecimalEncoder(json.JSONEncoder): def default(self, o): if isinstance(o, decimal.Decimal): if o % 1 > 0: return float(o) else: return int(o) return super(DecimalEncoder, self).default(o) # 本体 def lambda_handler(event, context): ##### 要素の削除 # リストのうち削除したい要素番号を定義しておく index = 0 res = table.update_item( Key={ # アップデートするレコードの条件 # 例: idカラム(プライマリキー)=1のとき 'id': 1, }, # Remove命令でリストから要素を削除する。 # 基本形: REMOVE カラム名[要素番号] # ExpressionAttributeValuesでの要素番号指定は(何故か)できないので、削除する要素番号が可変の場合は無理やり渡している UpdateExpression="REMOVE #attribute[" + str(index) + "]", ExpressionAttributeNames= { # UpadateExpressionで使っている#attributeを置き換える # リスト要素の名前、今回はtarget_listだと仮定する '#attribute': "target_list" }, # DB操作に直接影響しないので好みに合わせて ReturnValues="UPDATED_NEW" ) ##### 要素の追加 # 追加する要素には、数値・文字列・バイナリが指定可能 # boto経由だと、変数の型が考慮されるようなので注意(そのかわりN,S,Bの指定はいらない?) append_value = 0 res = table.update_item( Key={ # 例: idカラム(プライマリキー)=1のとき 'id': 1, }, # list_appendでlist同士をつなぎ、SET命令で新しいリストを代入する # 基本形: SET カラム名 = list_append(リスト1, リスト2) # list同士の結合命令なので、追加要素が一つしかなくてもリストの形で渡す # ExpressionAttributeValuesが使えるのでこちらを使ったほうがよさそう UpdateExpression="SET #attribute = list_append(#attribute, :val)", ExpressionAttributeNames= { # UpadateExpressionで使っている#attributeを置き換える # リスト要素の名前、今回はtarget_listだと仮定する '#attribute': "target_list" }, ExpressionAttributeValues={ # UpadateExpressionで使っている:valを実際の値で置き換える ':val': [append_value] }, # DB操作に直接影響しないので好みに合わせて ReturnValues="UPDATED_NEW" )
備考
Number Setに対して同じことをやろうとするときはADD命令を使うらしいが、うまく行かなかった。 botoで実現可能なのだろうか。。。