@aws-sdk/lib-dynamodb的delete()返回无效响应,如何判断删除是否成功?
我使用@aws-sdk/lib-dynamodb的DynamoDBDocument库实现了删除操作,代码如下:
import { DynamoDBDocument } from "@aws-sdk/lib-dynamodb"; export class DdbConector { ddbDoc: DynamoDBDocument; constructor(ddbClient: DynamoDBDocument) { this.ddbDoc = ddbClient; } async deleteItem(TableName: string, id: string): Promise<void> { const res = await this.ddbDoc.delete({ TableName, Key: { id } }) console.log(res) // 输出如下两种响应 } }
执行删除时,两种场景的响应输出如下:
删除成功(条目已存在并被删除)的响应:
{ '$metadata': { httpStatusCode: 200, requestId: 'c7a1e277-dc3e-40a1-9122-ad580484b56d', extendedRequestId: undefined, cfId: undefined, attempts: 1, totalRetryDelay: 0 }, Attributes: undefined, ConsumedCapacity: undefined, ItemCollectionMetrics: undefined }
删除失败(未找到对应条目)的响应:
{ '$metadata': { httpStatusCode: 200, requestId: '3fdd38b8-e7e2-4bfe-9541-7f0aab49d6b6', extendedRequestId: undefined, cfId: undefined, attempts: 1, totalRetryDelay: 0 }, Attributes: undefined, ConsumedCapacity: { CapacityUnits: 1, GlobalSecondaryIndexes: undefined, LocalSecondaryIndexes: undefined, ReadCapacityUnits: undefined, Table: undefined, TableName: 'Customers', WriteCapacityUnits: undefined }, ItemCollectionMetrics: undefined }
因为DynamoDB的响应无法直接体现操作是否成功(比如是否真的删除了条目),目前我只能再次查询条目来验证delete()是否成功。请问有没有更合适的解决方法?
方法1:使用ReturnValues参数获取被删除的条目
DynamoDB的delete操作支持ReturnValues参数,设置为ALL_OLD时,会返回被删除的条目属性。如果返回的Attributes不为undefined,说明条目存在并被成功删除;如果Attributes为undefined,则说明目标条目不存在,删除操作没有实际执行。
修改你的deleteItem方法:
async deleteItem(TableName: string, id: string): Promise<boolean> { const res = await this.ddbDoc.delete({ TableName, Key: { id }, ReturnValues: "ALL_OLD" // 关键参数 }); // Attributes存在则表示成功删除了已有条目 return res.Attributes !== undefined; }
调用该方法时,返回true表示确实删除了一个存在的条目,false表示目标条目不存在,无实际删除操作。
方法2:使用条件表达式强制检查条目存在
如果你希望在条目不存在时直接抛出错误(而非返回布尔值),可以用ConditionExpression指定删除的前提条件:仅当条目存在时才执行删除。
示例代码:
async deleteItem(TableName: string, id: string): Promise<void> { try { await this.ddbDoc.delete({ TableName, Key: { id }, ConditionExpression: "attribute_exists(id)" // 确保id对应的条目存在 }); // 执行到此处说明删除成功 } catch (error) { if (error.name === "ConditionalCheckFailedException") { // 条目不存在,处理该场景 throw new Error("目标条目不存在,无法执行删除"); } // 其他错误直接抛出 throw error; } }
这种方式下,若条目不存在,DynamoDB会抛出ConditionalCheckFailedException,捕获该异常即可判断操作未成功,无需额外查询。
方法3:利用ConsumedCapacity辅助判断(不推荐)
从你提供的响应来看,删除不存在的条目时会返回ConsumedCapacity,而删除成功时该字段为undefined。但这种判断方式不可靠:ConsumedCapacity的返回取决于请求中是否设置了ReturnConsumedCapacity参数(默认可能不返回),且AWS API行为可能变更,因此优先推荐前两种方法。
内容的提问来源于stack exchange,提问作者Naim Gürleyük

