DynamoDB如何更新地图,如果属性存在,否则默默忽略
我有一个表产品,其关键是范围:orgzviceid + productid。它有一个名为“结账”地图属性,并称为“prod_stk_qty_i_i”数量将存储属性。假设检验ID是5,并且检验了产品ID 34中的2个数量,则对于具有产品ID 34的产品,总可用数量是10.一旦推车检验发生,假设检验ID是5,产品(为的productid 34) “结账” 映射项和 “prod_stk_qty_i_i” 在DynamoDB会是这样的:DynamoDB如何更新地图,如果属性存在,否则默默忽略
"checkout" : { "5" : 2 },
"prod_stk_qty_i_i" : 8
如果另一个结账发生同样的产品(比如1个数量),并且如果该结账ID是7,那么n如此的结帐:
"checkout" : { "5" : 2, "7" : 1 },
"prod_stk_qty_i_i" : 7
如果付款,结帐条目被删除,数量增加。
现在,我的要求是定期在超时(30分钟)之后,发布已签出但未发布的产品数量。我通过
- 做到这一点通过增加数量“结账”的价值
- 取出结账。 map条目
即使多次尝试此操作(幂等),此操作也不会失败,这一点很重要,所以它必须只在checkout.checkoutID字段存在时更新。如果不是,它应该简单地忽略。
我试过如下:
[
"UpdateItem",
[
{
"TableName": "Products",
"Key": {
"orgzviceid": {
"N": "3000161710"
},
"productid": {
"N": "11"
}
},
"UpdateExpression": "REMOVE #checkout.#checkoutID SET #prod_stk_qty_i_i = #prod_stk_qty_i_i + #checkout.#checkoutID",
"ExpressionAttributeNames": {
"#checkout": "checkout",
"#checkoutID": "235",
"#prod_stk_qty_i_i": "prod_stk_qty_i_i"
},
"ConditionExpression": "attribute_exists(#checkout.#checkoutID)",
"ReturnValues": "ALL_NEW"
}
]
]
但是,它给了我万一结账条目中找不到用于结帐ID 235.注意,我已经写ConditionExpression做更新只有当错误属性“condition.235”存在。
错误日志:
com.amazonaws.dynamodb.v20120810#ConditionalCheckFailedException”, “消息”: “其 条件请求失败...”
所以,我怎样写一个查询,如果映射条目存在,那么执行上述操作,其他方式不会失败? 很明显,一个不好的办法是首先检查一个GetItem查询,如果检查条目存在提供的CheckoutID,然后只做这个但是,它似乎并不正确
我相信你错误地使用条件表达式。如果某些标准未得到满足,条件的一点就是失败。为什么你有条件呢?没有条件,它只会执行更新表达式,如果该项不存在,我不会指望你得到一个错误。就像查询不存在的项目一样。你应该简单地得到一个空集。不是一个错误。
您的方法不起作用,因为您在条件表达式中混合了“Attribute”和“AttributeValue”。让我来解释:
"ConditionExpression": "attribute_exists(#checkout.#checkoutID)"
在你的桌子,结账是发电机dB的属性,而checkoutID绝不相关的表模式。因此对于发电机数据库,checkoutID是属性值的一部分,而不是属性本身。
因此,有条件,你做不会工作。 您的用例的条件表达式将表示属性检出存在,它的值是。但是,为了做到这一点,您需要传递预计的地图,这可以归结为在更新之前读取记录。
我确实认为阅读记录,更新值并坚持它应该是在这种情况下继续前进的方式(并不一定是个坏主意) 在这种情况下,考虑使用某种乐观锁防止脏读取和写入。
如果我的要求是做一个“更新IF条件”? – Ouroboros
条件表达式的要点是对操作强加一个条件。这可能是失败/断言用户想要的任何东西。 – Rahul