为什么 "documentClient.put" 在 DynamoDB 中执行更新而不是插入?

Why "documentClient.put" is doing UPDATE instead of INSERT in DynamoDB?

我有一个简单的逻辑,我想 INSERT 使用 AWS.DynamoDB.DocumentClient 在 table 中记录。下面是我正在使用的代码。在这里,我注意到 .put 正在更新记录,但不确定原因。

在 CW 中检查日志时,我没有看到任何错误,所以不确定我在这里遗漏了什么。

代码:

async addEvent(incomingModel: MyModel): Promise <MyModel> {
    const dynamoModel: MyModel = {
        fieldOne: incomingModel.fieldOne,
        fieldTwo: incomingModel.fieldTwo,
        "One#two#three": `${incomingModel.one}#${incomingModel.two}#${incomingModel.three}`,
        fieldThree: incomingModel.fieldThree,
        fieldFour: incomingModel.fieldFour,
    };

    var params = {
        TableName: 'Table',
        Item: dynamoModel,
    };

    return this.documentClient
        .put(params)
        .then((data) => {
            this.logger.debug(
                "Response received from Dynamo after adding an incomingModel",
                data,
                this.constructor.name,
            );

            return data as MyModel;
        })
        .catch((error) => {
            const errorMessage = JSON.stringify(error);
            this.logger.error(
                `Error creating incomingModel with body of ${errorMessage}`,
                error,
                this.constructor.name,
            );
            throw error;
        });
}

这是 put 操作的预期行为。来自 docs(强调我的):

Creates a new item, or replaces an old item with a new item. If an item that has the same primary key as the new item already exists in the specified table, the new item completely replaces the existing item.

如 Seth 所述,这是 DynamoDb 的默认行为。

您可以使用“ConditionExpression”来避免更新。在我的示例中,我将 'PK' 命名为 HashKey,并将 'SK' 命名为 RangeKey:

async function put(Item, TableName){
    const params = {
        TableName,
        Item,
        ExpressionAttributeNames : {
            '#pk' : 'PK',
            '#sk' : 'SK',
        },
        ConditionExpression : 'attribute_not_exists(#pk) AND attribute_not_exists(#sk)',
    };
    
    const result = await documentClient.put(params).promise();
    
    // ... do the rest....

}

如果项目已经存在(两个键都匹配)交易将失败并给出 "ConditionalCheckFailedException: The conditional request failed"

希望对你有用!