[英]How to append a value to list attribute on AWS DynamoDB?
我使用 DynamoDB 作为 KV 数据库(因为没有太多数据,我认为这很好),并且“V”的一部分是列表类型(大约 10 个元素)。 有一些会话可以向其附加新值,但我找不到在 1 个请求中执行此操作的方法。 我所做的是这样的:
item = self.list_table.get_item(**{'k': 'some_key'})
item['v'].append('some_value')
item.partial_save()
我先请求服务器,修改值后保存。 这不是原子的,看起来很难看。 有没有办法在一个请求中做到这一点?
以下代码适用于 boto3:
table = get_dynamodb_resource().Table("table_name")
result = table.update_item(
Key={
'hash_key': hash_key,
'range_key': range_key
},
UpdateExpression="SET some_attr = list_append(some_attr, :i)",
ExpressionAttributeValues={
':i': [some_value],
},
ReturnValues="UPDATED_NEW"
)
if result['ResponseMetadata']['HTTPStatusCode'] == 200 and 'Attributes' in result:
return result['Attributes']['some_attr']
这里的 get_dynamodb_resource 方法只是:
def get_dynamodb_resource():
return boto3.resource(
'dynamodb',
region_name=os.environ['AWS_DYNAMO_REGION'],
endpoint_url=os.environ['AWS_DYNAMO_ENDPOINT'],
aws_secret_access_key=os.environ['AWS_SECRET_ACCESS_KEY'],
aws_access_key_id=os.environ['AWS_ACCESS_KEY_ID'])
通过将UpdateItem
API 与UpdateExpression
结合使用,您可以在 1 个请求中完成此UpdateExpression
。 由于您想附加到列表,您可以将SET
操作与list_append
函数一起使用:
SET
支持以下功能:...
list_append (operand, operand)
- 计算结果为添加了新元素的列表。 您可以通过反转操作数的顺序将新元素附加到列表的开头或结尾。
您可以在使用更新表达式修改项目和属性文档中看到这方面的几个示例:
以下示例向FiveStar评论列表添加了一个新元素。 表达式属性名称
#pr
是ProductReviews ; 属性值:r
是一个单元素列表。 如果列表之前有两个元素[0]
和[1]
,那么新元素将是[2]
。SET #pr.FiveStar = list_append(#pr.FiveStar, :r)
下面的示例将另一个元素添加到FiveStar评论列表,但这次该元素将附加到列表的开头
[0]
。 列表中的所有其他元素都将移动一个。SET #pr.FiveStar = list_append(:r, #pr.FiveStar)
#pr
和:r
使用占位符作为属性名称和值。 您可以在“ 为属性名称和值使用占位符”文档中查看有关这些内容的更多信息。
我会看看更新表达式: http : //docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.Modifying.html#Expressions.Modifying.UpdateExpressions.ADD
应该可以使用 ADD,尽管不确定 boto 中的支持是什么。
@LaserJesus 的答案是正确的。 但是,直接使用 boto3 是一种痛苦,难以维护,并且根本无法重用。 dynamof抽象了那些垃圾。 使用dynamof
将项目附加到列表属性看起来像:
from functools import partial
from boto3 import client
from dynamof.executor import execute
from dynamof.operations import update
from dynamof.attribute import attr
client = client('dynamodb', endpoint_url='http://localstack:4569')
db = partial(execute, client)
db(update(
table_name='users',
key={ 'id': user_id },
attributes={
'roles': attr.append('admin')
}))
免责声明:我写了dynamof
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.