[英]Equivalent of insert or update in DynamoDB for counting
我正在尝试跟踪来自 IP 地址的命中。
通常,在 SQL 数据库中,您可以执行以下操作:
CREATE TABLE website_hits
(
ip VARCHAR(45) PRIMARY KEY,
hits INTEGER NOT NULL
);
INSERT INTO website_hits
VALUES ("1.2.3.4", 1)
ON DUPLICATE KEY UPDATE hits = hits + 1;
DynamoDB 提供了执行原子更新的功能,其中更新表达式作为UpdateItem请求的一部分提供,这意味着它不能用于创建类似于上面显示的INSERT
查询的条目:
$ aws dynamodb update-item --table-name WebsiteHits --key '{"ip":{"S":"1.2.3.4"}}' --update-expression 'SET hits = hits + :incr' --expression-attribute-values '{":incr":{"N":"1"}}' --return-values UPDATED_NEW
An error occurred (ValidationException) when calling the UpdateItem operation: The provided expression refers to an attribute that does not exist in the item
显然缺少此功能将使我不得不先执行 GetItem 后跟 UpdateItem,如果有多个进程同时尝试写入数据库,这将导致将不正确的值写回数据库。
我 go 如何实现类似于上面显示的ON DUPLICATE KEY UPDATE
语句的插入或更新?
您看到此异常的原因是您的项目当前不存在hits
属性,从而导致异常:
提供的表达式引用了项中不存在的属性
ADD
而不是SET
这是推荐的方法。 如果该值不存在,它会自动将其设置为 0,然后添加您提供的值。 您唯一会使用选项 #2 的情况是当属性存储在嵌套值中时, ADD
对此不起作用。
在更新表达式中使用 ADD 操作将新属性及其值添加到项目中。 文档
ADD path value
python
table.update_item(
Key={'ip': '1.2.3.4'},
UpdateExpression="ADD #hits :incr",
ExpressionAttributeNames={'#hits': 'hits'},
ExpressionAttributeValues={':incr': 1}
)
bash
$ aws dynamodb update-item \
--table-name WebsiteHits \
--key '{"ip":{"S":"1.2.3.4"}}' \
--update-expression 'ADD #hits :incr' \
--expression-attribute-values '{":incr":{"N":"1"}}' \
--return-values UPDATED_NEW
if_not_exists
Function如果项目不包含指定路径的属性,则 if_not_exists 的计算结果为 value; 否则,它计算为路径。
这种方法要求您设置一个值,如果该属性不应存在,则该值最初设置为: :empty=0
。 与建议您在 DynamoDB 中添加值的方式相比,这更像是一种解决方法。
if_not_exists (path, value)
python
table.update_item(
Key={'voter': 'default_voter'},
UpdateExpression="set #hits = if_not_exists(#hits, :empty) + :incr",
ExpressionAttributeNames={'#hits': 'hits'},
ExpressionAttributeValues={':incr': 1, ':empty': 0}
)
bash
$ aws dynamodb update-item \
--table-name WebsiteHits \
--key '{"ip":{"S":"1.2.3.4"}}' \
--update-expression 'set #hits = if_not_exists(#hits, :empty) + :incr' \
--expression-attribute-values '{":incr":{"N":"1"}}' \
--return-values UPDATED_NEW
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.