我有一个带有复合键的 DynamoDB 表,如下所示:
| PK | SK | 类型 | 电子邮件 | 描述 |
|---|---|---|---|---|
| 用户#A | 用户#A | 用户 | a@example.com | |
| 用户#A | 错误#1 | 漏洞 | 这看起来不错 | |
| 用户#B | 错误#2 | 漏洞 | 我的用户不是首先创建的! |
我想确保在添加相关的“Bug”记录之前存在“User”记录 - 所以这里的第三项是不正确的。
当我将bug 项目与条件放在一起attribute_exists(PK)时,条件永远不会为真。当我删除条件时,我最终得到第三行;没有对应用户的错误。
我的理解是,attribute_exists()无论您提供哪个属性,都只查看具有组合复合键的项目,而不是整个表。
在这种情况下,是否有一种方法可以确保存在具有相同分区键的项目,同时忽略排序键?
DynamoDB 条件表达式可能会令人困惑,而文档可能会加剧该问题!
DynamoDB 条件表达式的工作原理是:1) 查找项目,2) 评估条件表达式,最后 3) 如果条件评估为 true,则写入数据库。
我假设你的put操作看起来像这样:
ddbClient.put({
TableName: "YOUR TABLE",
Item: {
PK: "USER#B",
SK: "BUG#2",
Type "Bug",
Description: "My user wasn't created first!"
},
ConditionExpression: "attribute_exists(PK)"
})
Run Code Online (Sandbox Code Playgroud)
在此示例中,DynamoDB 首先尝试查找 PK: "USER#B" SK: "BUG#2" 的项目,但该项目不存在。正如您所遇到的,该项目不会写入DynamoDB,因为具有该主键的项目不存在。
正如您在问题中提到的,您看到的问题是 aCondttionExpression仅适用于单个项目。但是,您尝试通过将条件应用于另一个put项目来对数据库中的一个项目进行条件化。这是 DynamoDB事务的绝佳候选者。
事务使您可以将操作分组到“全有或全无”操作中。如果事务中的一项操作失败,则整个事务将失败并且所有操作都不会应用。
通过采取这种方法,您可以实现您所追求的目标
ddbClient.transactWriteItems({
TransactItems=[
{ "PUT":
{
TableName: "YOUR TABLE",
Item: {
PK: "USER#B",
SK: "BUG#2",
Type "Bug"
}
}
},
{ "ConditionCheck":
{
TableName: "YOUR TABLE",
Item: {
PK: "USER#B",
SK: "USER#B"
},
ConditionExpression: "attribute_exists(PK)"
}
}
]
})
Run Code Online (Sandbox Code Playgroud)
在上面的事务中,我在输入错误之前使用ConditionCheck来确认用户的存在。如果用户不存在,则事务将失败,并且错误不会写入DDB。
有关 DynamoDB 条件表达式的更全面说明,我强烈建议您查看Alex Debrie 撰写的了解 DynamoDB 条件表达式。
| 归档时间: |
|
| 查看次数: |
3180 次 |
| 最近记录: |