#概要
DynamoDBの属性を更新する際、対象の属性名があらかじめ決まっている場合は Expression 式に固定の attribute を入れてあげればいいのですが、更新対象の属性が状況に応じて変化する場合はそうはいかないので、引数に応じて文字列結合でその都度 Expression 式を生成するような非同期関数を作成しました。
#update(更新)
以下、サンプルの非同期関数です。
AWS.DynamoDB.DocumentClient を利用して実装しています。
引数として渡された、 item オブジェクトの要素に応じて、 updateExpression, expressionAttributeValues, expressionAttributeNames の文字列を生成し、update メソッドで利用するようにしています。
public async updateItem(item: {
HashKey: string;
RangeKey: string;
AttributeA?: string;
AttributeB?: string;
AttributeC?: string;
AttributeD?: string;
}): Promise<DynamoDB.DocumentClient.UpdateItemOutput> {
let updateExpression = "set ";
const expressionAttributeValues = {} as any;
const expressionAttributeNames = {} as any;
// item の要素から expression 文字列を生成する
for (const [key, value] of Object.entries(item)) {
// ハッシュキー or レンジキーは取り除く
if (!(key === "HashKey" || key === "RangeKey")) {
updateExpression += `#${key} = :${key}, `;
expressionAttributeValues[`:${key}`] = value;
expressionAttributeNames[`#${key}`] = `${key}`;
}
}
// 末尾の不要文字を削除
updateExpression = updateExpression.slice(0, -2);
// update メソッドの実行
return await documentclient
.getClient()
.update({
TableName: "table-name",
Key: {
HashKey: item.HashKey,
RangeKey: item.RangeKey,
},
UpdateExpression: updateExpression,
ExpressionAttributeValues: expressionAttributeValues,
ExpressionAttributeNames: expressionAttributeNames,
ConditionExpression:
"attribute_exists(HashKey) AND attribute_exists(RangeKey)",
ReturnValues: "ALL_NEW",
})
.promise();
}
#まとめ
引数に応じて Expression 式を変化させるような AWS.DynamoDB.DocumentClient の 非同期関数を作成しました。
実際に少しはまりましたが、DynamoDBの接続処理は非同期で呼び出されるため取り扱いには注意です。