我有一个带有包含嵌套地图的属性的dynamodb表,我想更新一个特定的库存项目,该项目通过一个过滤器表达式进行过滤,从而从该地图中生成单个项目。
如何编写一个更新表达式以将其名称更新为name = opel的项目的“到位三”,标签包括“ x1”(可能还有f3)? 这应该只更新第一个列表元素的location属性。
memcpy
答案 0 :(得分:6)
更新的答案-基于更新的问题陈述
您可以使用update expressions更新嵌套地图中的属性,以便仅更新项目的一部分(即DynamoDB将对您的项目应用补丁的等效项),但是,因为DynamoDB是文档数据库,所有操作(输入,获取,更新,删除等)对整个项目都起作用。
因此,在您的示例中,假设User
是分区键,并且没有排序键(在该示例中我没有看到任何可能是排序键的属性),那么更新请求可能看起来像这样:
table.update_item(
Key={
'User': 'test'
},
UpdateExpression="SET #inv[0].#loc = :locVal",
ExpressionAttributeNames={
'#inv': 'inventory',
'#loc': 'location'
},
ExpressionAttributeValues={
':lovVal': 'in place three',
},
)
也就是说,您必须知道项目架构的外观以及应该正确更新项目中的哪些属性。
DynamoDB无法对子项目进行操作。意思是,没有办法告诉Dynamo执行诸如“更新项目之类的操作,设置具有'name'等于'opel'的属性的'inventory'数组元素的'location'属性。 / em>
这可能不是您想要的答案,但是今天已经可以使用了。通过稍微更改架构,您也许可以更接近所需。
如果您需要按名称引用子项,则可以存储以下内容:
{
"inventory": {
"opel": {
"location": "in place one", # I want to update this
"tags": [ "x1", "f3" ]
},
"abc": {
"location": "in place two",
"tags": [ "a3", "f5" ]
}
},
"User" :"test"
}
那么您的查询将是:
table.update_item(
Key={
'User': 'test'
},
UpdateExpression="SET #inv.#n.#loc = :locVal",
ExpressionAttributeNames={
'#inv': 'inventory',
'#loc': 'location',
'#n': 'opel'
},
ExpressionAttributeValues={
':lovVal': 'in place three',
},
)
但是YMMV还是有局限性的,因为您只能按名称识别库存物品(即,您仍然不能说“使用标签'x1'更新库存”
最终,您应该仔细考虑为什么需要Dynamo来为您执行这些复杂的操作,而不是具体说明要更新的内容。
答案 1 :(得分:0)
您可以按以下方式更新嵌套地图:
首先创建并清空 map 类型的 item属性。在示例中,图形是空项目属性。
dynamoTable = dynamodb.Table('abc')
dynamoTable.put_item(
Item={
'email': email_add,
'graph': {},
}
>
brand_name ='opel'
DynamoTable = dynamodb.Table('abc')
dynamoTable.update_item(
Key={
'email': email_add,
},
UpdateExpression="set #Graph.#brand= :name, ",
ExpressionAttributeNames={
'#Graph': 'inventory',
'#brand': str(brand_name),
},
ExpressionAttributeValues = {
':name': {
"location": "in place two",
'tag': {
'graph_type':'a3',
'graph_title': 'f5'
} }
答案 2 :(得分:0)
更新Mike的答案,因为这种方式不再起作用了(至少对我而言)。
现在这样工作(注意UpdateExpression
和ExpressionAttributeNames
):
table.update_item(
Key={
'User': 'test'
},
UpdateExpression="SET inv.#brand.loc = :locVal",
ExpressionAttributeNames={
'#brand': 'opel'
},
ExpressionAttributeValues={
':locVal': 'in place three',
},
)
无论Key={}
中有什么内容,它始终是分区键(和排序键,如果有的话)。
编辑:
似乎这种方式仅适用于2级嵌套属性。在这种情况下,您只能将“ ExpressionAttributeNames”用于“中间”属性(在本示例中,该属性为#brand
:inv.#brand.loc
)。我现在还不确定什么是真正的规则。