Amazon dynamodb 是否可以在DynamoDB中向上插入嵌套字段?
我想在DynamoDB中“插入”一个文档。也就是说,我想指定一个键和一组字段/值对。如果不存在具有该键的文档,我希望使用该键和我指定的键/值对创建一个文档。如果存在具有该键的文档,我希望将我指定的字段设置为指定的值(如果这些字段以前不存在,则应添加它们)。现有文档上的任何其他未指定字段都应保留 当我设置的字段/值对都是顶级字段时,我似乎可以很好地处理这个调用。如果我有嵌套结构,Amazon dynamodb 是否可以在DynamoDB中向上插入嵌套字段?,amazon-dynamodb,upsert,Amazon Dynamodb,Upsert,我想在DynamoDB中“插入”一个文档。也就是说,我想指定一个键和一组字段/值对。如果不存在具有该键的文档,我希望使用该键和我指定的键/值对创建一个文档。如果存在具有该键的文档,我希望将我指定的字段设置为指定的值(如果这些字段以前不存在,则应添加它们)。现有文档上的任何其他未指定字段都应保留 当我设置的字段/值对都是顶级字段时,我似乎可以很好地处理这个调用。如果我有嵌套结构,UpdateItem将用于设置嵌套字段,只要该结构存在。换句话说,如果我的现有文档有“foo”:{},那么我可以成功设置
UpdateItem
将用于设置嵌套字段,只要该结构存在。换句话说,如果我的现有文档有“foo”:{}
,那么我可以成功设置“foo.bar”:42
但是,如果已经没有foo
对象,我似乎无法设置“foo.bar”:42
(比如在没有指定字段的文档的情况下,我的“upsert”表现为“insert”)
几年前我在AWS论坛上发现,这似乎意味着我想做的事情做不到,但我希望这一点最近有所改变,或者有人知道怎么做
UpdateItem
的行为类似于“upsert”操作:如果表中存在该项,则更新该项,如果不存在,则添加(插入)一个新项。
可以使用以下查询实现(“foo.bar”:42):
table.update_item(Key = {'Id' : id},
UpdateExpression = 'SET foo = :value1',
ExpressionAttributeValues = {':value1': {'bar' : 42}}
)
希望这有帮助:)我发现这个更新项限制(顶级属性与嵌套属性)也令人沮丧。最终我找到了这个答案,并且能够解决这个问题: 它需要两个UpdateItem调用(可能更多,具体取决于嵌套级别?)。我只需要一个关卡,所以我就是这样做的:
{
"partition_key": "key",
"top_level_attribute": {
"nested_attribute": "value"
}
}
python代码:
def upsert_nested_item(self, partition_key, top_level_attribute_name, nested_attribute_name, nested_item_value):
try:
self.table.update_item(
Key={'partition_key': partition_key},
ExpressionAttributeNames={f'#{top_level_attribute_name}': top_level_attribute_name},
ExpressionAttributeValues={':empty': {}},
ConditionExpression=f'attribute_not_exists(#{top_level_attribute_name})',
UpdateExpression=f'SET #{top_level_attribute_name} = :empty',
)
except self.DYNAMODB.meta.client.exceptions.ConditionalCheckFailedException:
pass
self.table.update_item(
Key={'partition_key': partition_key},
ExpressionAttributeNames={
f'#{top_level_attribute_name}': top_level_attribute_name,
f'#{nested_attribute_name}': nested_attribute_name
},
ExpressionAttributeValues={f':{top_level_attribute_name}': nested_item_value},
UpdateExpression=f'SET #{top_level_attribute_name}.#{nested_attribute_name} = :{top_level_attribute_name}',
)
为了给你另一个数据点,我在2015年5月(ish)研究了这个问题,你提到的同样的问题仍然存在。我无法实现嵌套字段upsert的目标,因此我必须改变解决该问题的方法以及存储数据的方式。@mkobit感谢您的数据点;这也是我得出的结论。因为我的数据有固定数量的嵌套层,所以我最终将其存储为扁平的,带有名为
foo\u bar
的字段,并且我将编组/解编组代码添加到我的DAO层以对其进行翻译。这是一种痛苦,但在一年后的同一个问题上,它似乎运作得足够好(至少到目前为止)。恼人的是,Dynamo没有抛出错误,只是没有保存数据树的那部分。有人找到解决方案了吗?请在这里发帖。是的,我读过。但是如果你读了我的问题,我无法插入嵌套对象。我将它与嵌套对象一起使用,它工作正常(w/DynamoDBMapper)。但是,如果foo
的初始值除了您正在更新的bar
值之外还有其他键,它们不会丢失吗?例如,如果初始值是{foo:{biz:33,bar:0}}
,并且您只想更改foo.bar
,而保持foo
对象的其余部分不变,那么这是否可行?我已经回答了一个类似的问题。如果有效,请检查并评论。