仅当项目不存在时如何将项目放入 dynamodb

Dar*_*tar 6 amazon-web-services nosql amazon-dynamodb

我在 dynamodb 中有一个表,它只有一个分区键,并且只有当数据库中不存在具有相同分区键的另一个项目时,我才想将一个项目放入数据库中。

\n\n

我尝试使用 ConditionExpression attribute_not_exists 无济于事。

\n\n

问题是数据库中可能尚不存在某个项目,因此 attribute_not_exists 失败并显示\n无效的条件表达式:运算符或函数需要文档路径;运算符或函数:attribute_not_exists

\n\n

编辑:\n您能否发布您使用的完整条件表达式+表分区键的名称?\xe2\x80\x93

\n\n
Key: {\n  username: event.pathParameters.username\n},\nExpressionAttributeValues: {\n  ":username": event.pathParameters.username\n},\nItem: {\n    userId: event.requestContext.identity.cognitoIdentityId\n},\nConditionExpression: "attribute_not_exists(:username)"\n
Run Code Online (Sandbox Code Playgroud)\n

Ita*_*man 4

我只是在一个attributes_not_exists条件下尝试了一下,它似乎按预期工作:

$ aws create-table --table-name example1 \
  --attribute-definitions AttributeName=pk,AttributeType=S \
  --key-schema AttributeName=pk,KeyType=HASH  --billing-mode PAY_PER_REQUEST
...
$ aws dynamodb put-item --table-name example1 \
    --item '{"pk": {"S": "abc"}, "city": {"S": "NYC"}}'
$ aws scan --table-name example1
{
    "Items": [
        {
            "city": {
                "S": "NYC"
            },
            "pk": {
                "S": "abc"
            }
        }
    ],
    "Count": 1,
    "ScannedCount": 1,
    "ConsumedCapacity": null
}

$ aws dynamodb put-item --table-name example1 \
  --item '{"pk": {"S": "abc"}, "city": {"S": "SF"}}' \
  --condition-expression "attribute_not_exists(pk)"

An error occurred (ConditionalCheckFailedException) ... 

$
Run Code Online (Sandbox Code Playgroud)

为什么你的请求失败了?

根据您发布的请求,我认为罪魁祸首是您的条件表达式。

而不是"attribute_not_exists(:username)"应该是attribute_not_exists(username)。前缀:表示值占位符,而attribute_not_exists函数不需要值,它需要属性名称。进行更改后,您还需要删除该ExpressionAttributeValues字段,因为它定义的值占位符(即:):username不再在请求中的任何位置使用。

因此,总而言之,这个请求应该适合您:

Key: {
  username: event.pathParameters.username
},
Item: {
  userId: event.requestContext.identity.cognitoIdentityId
},
ConditionExpression: "attribute_not_exists(username)" 
Run Code Online (Sandbox Code Playgroud)

最后一条(超级小)评论:您发布的请求看起来像更新请求。我相信对于您的用例,您可以使用put,它需要一个更简单的请求。具体来说,如果put您只指定整个项目,则不需要与其他属性分开指定键。请注意,就像 一样updateput也支持ConditionExpression解决方案中的关键部分。