[英]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.