GUIでは一覧表示から全件チェックして削除できるが1度に実施するコマンドはない。
おそらくget-itemし表示しているデータを片っ端からdelete-itemしているのではなかろうか。
前方一致したレコードを全て削除する機会があり手でぽちぽちするのも面倒なので調べてみた。
そもそものputとdelete(CLI)
put-item
- 数字もクオーテーションでくくる。
- jsonも入れられる。ただ、クオートをエスケープする必要はある。
$ aws dynamodb put-item --table-name test --item '{"part":{"S":"hoge"}, "num":{"N":"1"}, "obj":{"S":"{\"test\": \"aaa\"}"}}'
- 同じパーティションキーで叩くとエラーはしないで勝手に上書きされる。
- そもそもレスポンスは何もない。
- 返値が欲しいときはオプションで色々指定できる。
$ aws dynamodb put-item --table-name test --item '{"part":{"S":"hoge2"}, "num":{"N":"2"}, "obj":{"S":"{\"test\": \"aaa\"}"}}' --return-consumed-capacity TOTAL
{
"ConsumedCapacity": {
"TableName": "test",
"CapacityUnits": 1.0
}
}
delete-item
-
--key
は必須。~~削除対象に該当するキーを一つ書いておけばいい?~~削除対象を指定 -
--key
がそもそも条件に当てはまっていないとエラーする → あとからわかったが当然 - このコマンドの条件は期待した条件に一致するものを全て削除するものではない。
-
--expression-attribute-values
ではファイルを指定しても直接書いてもいい -
--condition-expression
にダイレクトに書くと怒られる - 条件に
begins_with
などを指定する場合これらは関数としての記法を取る
→ https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html
OK
$ aws dynamodb delete-item --table-name test --key '{"part":{"S":"hoge"}}' --condition-expression "part = :part" --expression-attribute-values file://values.json
$ aws dynamodb delete-item --table-name test --key '{"part":{"S":"hoge"}}' --condition-expression "part = :part" --expression-attribute-values '{":part": {"S": "hoge"}}'
$ aws dynamodb delete-item --table-name test --key '{"part":{"S":"hoge"}}' --condition-expression "begins_with (part, :part)" --expression-attribute-values '{":part": {"S": "hoge"}}'
./values.json
{
":part": {"S": "hoge"}
}
NG
$ aws dynamodb delete-item --table-name test --key '{"part":{"S":"hoge"}}' --condition-expression "part = '{\"S\": \"hoge\"}'"
An error occurred (ValidationException) when calling the DeleteItem operation: Invalid ConditionExpression: Syntax error; token: "'", near: "= '{"
$ aws dynamodb delete-item --table-name test --key '{"part":{"S":"fuga"}}' --condition-expression "part = :part" --expression-attribute-values '{":part": {"S": "hoge"}}'
An error occurred (ConditionalCheckFailedException) when calling the DeleteItem operation: The conditional request failed
→ やりたいことはできないらしいので自分で組む必要があるっぽい。
条件に合致するデータを全件削除(boto3+lambda)
この記事を参考
import json
import boto3
from boto3.dynamodb.conditions import Key, Attr
TABLENAME='test'
dynamodb = boto3.client('dynamodb')
# 条件に一致するレコードを全て取得
def getRecords(flt, val):
records = []
ExclusiveStartKey = None
while True:
if ExclusiveStartKey == None:
response = dynamodb.scan(
TableName=TABLENAME,
FilterExpression=flt,
ExpressionAttributeValues=val,
Limit=2 # テストとして上限を超えるケースを起こしてみるため2を設定
)
else:
response = dynamodb.scan(
TableName=TABLENAME,
FilterExpression=flt,
ExpressionAttributeValues=val,
Limit=2, # テストとして上限を超えるケースを起こしてみるため2を設定
ExclusiveStartKey=ExclusiveStartKey
)
for res in response["Items"]:
records.append(res)
if "LastEvaluatedKey" in response:
ExclusiveStartKey = response["LastEvaluatedKey"]
else:
break
return records
# 指定条件のレコードを削除
def deleteRecords(flt):
dynamodb.delete_item(
TableName=TABLENAME,
Key=flt
)
return 0 # エラーハンドリングしたい
def lambda_handler(event, context):
targets = getRecords(
'begins_with(part, :part)',
{":part": {"S": "hoge"}}, # eventでパラメータを受け取るなどしたら汎用性上がりそう
)
print("get records")
print(targets)
for target in targets:
print(target["part"]["S"])
res = deleteRecords(
{'part': target["part"]}
)
return 0
ただ、この方法では削除1回1回にリクエストが発生するので一括してできる方法を検討したい。
なおbegins_with
はqueryでは指定できなそうなのでscanを使用した。
import json
import boto3
from boto3.dynamodb.conditions import Key, Attr
d = boto3.resource('dynamodb')
table = d.Table('test')
def lambda_handler(event, context):
g = []
ExclusiveStartKey = None
while True:
if ExclusiveStartKey == None:
response = table.query(
KeyConditionExpression=Key("part").begins_with("hoge"),
Limit=2
)
else:
response = table.query(KeyConditionExpression="part",Limit=2, ExclusiveStartKey=ExclusiveStartKey)
g.extend(response["Items"])
if ("LastEvaluatedKey" in response) == True:
ExclusiveStartKey = response["LastEvaluatedKey"]
else:
break
print(g)
"errorMessage": "An error occurred (ValidationException) when calling the Query operation: Query key condition not supported"