更新嵌套地图 dynamodb

新手上路,请多包涵

我有一个 dynamodb 表,其属性包含一个嵌套地图,我想更新一个特定的库存项目,该项目是通过一个过滤器表达式过滤的,该过滤器表达式从该地图中生成一个项目。

如何编写更新表达式以将位置更新为名称 = opel 的项目的“就地三”,标签包括“x1”(可能还有 f3)?这应该只更新第一个列表元素的位置属性。

   {
    "inventory": [
    {
      "location": "in place one",      # I want to update this
      "name": "opel",
      "tags": [
        "x1",
        "f3"
      ]
    },
    {
      "location": "in place two",
      "name": "abc",
      "tags": [
        "a3",
        "f5"
      ]
    }],
    "User" :"test"
  }

原文由 Nico Müller 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 354
2 个回答

更新的答案 - 基于更新的问题陈述

您可以使用 更新表达式更新 嵌套映射中的属性,这样只有项目的一部分会得到更新(即 DynamoDB 将对您的项目应用等效的补丁)但是,因为 DynamoDB 是一个文档数据库,所以所有操作(Put 、获取、更新、删除等)作为一个整体处理项目。

因此,在您的示例中,假设 User 是分区键并且没有排序键(在该示例中我没有看到任何可能是排序键的属性),更新请求可能看起来像这个:

 table.update_item(
  Key={
    'User': 'test'
  },
  UpdateExpression="SET #inv[0].#loc = :locVal",
  ExpressionAttributeNames={
    '#inv': 'inventory',
    '#loc': 'location'
  },
  ExpressionAttributeValues={
    ':locVal': 'in place three',
  },
)

也就是说,您必须知道项目架构是什么样的以及项目中的哪些属性应该准确更新。

DynamoDB 没有办法对子项进行操作。意思是,没有办法告诉 Dynamo 执行诸如 “更新项目,设置‘inventory’数组元素的‘location’属性,这些元素的属性‘name’等于‘opel’”

这可能不是您所希望的答案,但它是当今可用的答案。您可以通过稍微更改架构来更接近您想要的内容。

如果您需要按名称引用子项,可能存储如下内容:

 {
  "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.#brand.#loc = :locVal",
  ExpressionAttributeNames={
    '#inv': 'inventory',
    '#loc': 'location',
    '#brand': 'opel'
  },
  ExpressionAttributeValues={
    ':locVal': 'in place three',
  },
)

但是 YMMV 即使这样也有局限性,因为您只能按名称识别库存项目(即,您仍然不能说“使用标签 ‘x1’ 更新库存”

最终,您应该仔细考虑为什么需要 Dynamo 为您执行这些复杂的操作,而不是具体说明要更新的内容。

原文由 Mike Dinescu 发布,翻译遵循 CC BY-SA 4.0 许可协议

您可以按如下方式更新嵌套地图:

  1. 首先创建并清空 map 类型的 _项目属性_。在示例 中是空项目属性。
    dynamoTable = dynamodb.Table('abc')
   dynamoTable.put_item(
       Item={
           'email': email_add,
           'graph': {},
       }

  1. 更新嵌套地图如下:
    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'
               }
           }

原文由 Shreya Rajput 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题