Python 如何将值附加到 AWS DynamoDB 上的列表属性?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31288085/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to append a value to list attribute on AWS DynamoDB?
提问by kxxoling
I'm using DynamoDB as an K-V db (cause there's not much data, I think that's fine) , and part of 'V' is list type (about 10 elements). There's some session to append a new value to it, and I cannot find a way to do this in 1 request. What I did is like this:
我使用 DynamoDB 作为 KV 数据库(因为没有太多数据,我认为这很好),并且“V”的一部分是列表类型(大约 10 个元素)。有一些会话可以向其附加新值,但我找不到在 1 个请求中执行此操作的方法。我所做的是这样的:
item = self.list_table.get_item(**{'k': 'some_key'})
item['v'].append('some_value')
item.partial_save()
I request the server first and save it after modified the value. That's not atomic and looks ugly. Is there any way to do this in one request?
我先请求服务器,修改值后保存。这不是原子的,看起来很难看。有没有办法在一个请求中做到这一点?
采纳答案by LaserJesus
The following code should work with boto3:
以下代码适用于 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']
The get_dynamodb_resource method here is just:
这里的 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'])
回答by Mircea
I would look at update expressions: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.Modifying.html#Expressions.Modifying.UpdateExpressions.ADD
我会看看更新表达式:http: //docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.Modifying.html#Expressions.Modifying.UpdateExpressions.ADD
Should be doable with an ADD, although not sure what the support in boto is for this.
应该可以使用 ADD,尽管不确定 boto 中的支持是什么。
回答by mkobit
You can do this in 1 request by using the UpdateItem
API in conjunction with an UpdateExpression
. Since you want to append to a list, you would use the SET
action with the list_append
function:
您可以通过将UpdateItem
API 与UpdateExpression
. 由于您想附加到列表,您可以使用SET
带有list_append
函数的操作:
SET
supports the following functions:...
list_append (operand, operand)
- evaluates to a list with a new element added to it. You can append the new element to the start or the end of the list by reversing the order of the operands.
SET
支持以下功能:...
list_append (operand, operand)
- 评估为添加了新元素的列表。您可以通过反转操作数的顺序将新元素附加到列表的开头或结尾。
You can see a couple examples of this on the Modifying Items and Attributes with Update Expressions documentation:
您可以在使用更新表达式修改项目和属性文档中看到这方面的几个示例:
The following example adds a new element to the FiveStarreview list. The expression attribute name
#pr
is ProductReviews; the attribute value:r
is a one-element list. If the list previously had two elements,[0]
and[1]
, then the new element will be[2]
.SET #pr.FiveStar = list_append(#pr.FiveStar, :r)
The following example adds another element to the FiveStarreview list, but this time the element will be appended to the start of the list at
[0]
. All of the other elements in the list will be shifted by one.SET #pr.FiveStar = list_append(:r, #pr.FiveStar)
以下示例向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)
The #pr
and :r
are using placeholders for the attribute names and values. You can see more information on those on the Using Placeholders for Attribute Names and Values documentation.
在#pr
和:r
正在使用的属性名称和值的占位符。您可以在“为属性名称和值使用占位符”文档中查看有关这些内容的更多信息。
回答by rayepps
@LaserJesus 's answer is correct. However, using boto3 directly is kind of a pain, hard to maintain, and not at all reusable. dynamofabstracts that junk away. Using dynamof
appending an item to a list attribute would look like:
@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')
}))
disclaimer: I wrote dynamof
免责声明:我写了dynamof