简体   繁体   English

在 Dynamo 中更新 object 的某些属性

[英]Updating certain attributes of an object in Dynamo

I have a DynamoDB table Policies and the object inside the table is as pages .我有一个 DynamoDB 表Policies ,表内的 object 是pages The schema of pages looks like this - pages架构如下所示 -

{
    "pages": {
      "default": [
       {
        "label": "Blocked",
        "bodyMessage": "This content is restricted by your organisation.",
        "pageId": "defaultblocked",
        "pageTitle": "Content Blocked",
        "url": "some.s3.url"
       },
       {
        "label": "Warning",
        "bodyMessage": "This content is not suitable.",
        "pageId": "defaultwarning",
        "pageTitle": "Not Recommended",
        "url": "some.s3.url"
       },
       {
        "label": "Security Risk",
        "bodyMessage": "This content is risky.",
        "pageId": "defaultsecurityrisk",
        "pageTitle": "Risky Content",
        "url": "some.s3.url"
       },
       {
        "label": "Cloud Application",
        "bodyMessage": "This content is risky.",
        "pageId": "defaultcloudapplication",
        "pageTitle": "Cloud Application",
        "url": "some.s3.url"
       }
      ]
     }
}

I want to update pageTitle & bodyMessage of each object of pages.default but the values of each object would differ from each other.我想更新pageTitle的每个 object 的pages.defaultbodyMessage ,但是每个 object 的值会彼此不同。

For example, object with pageId as defaultblocked would have values as -例如,将pageId设置为 defaultblocked 的defaultblocked将具有以下值 -

{
  "defaultblocked":{
    "pageTitle":"Some title",
    "bodyMessage":"Some message"
  }
}

So based on pageID the object from the pages.default should be selected & the attributes pageTitle & bodyMessage should be updated.因此,基于pageID ,应该选择 pages.default 中的pages.default并且应该更新属性pageTitlebodyMessage

This is how the entire object would look like -这就是整个 object 的样子——

{
  "defaultblocked":{
    "pageTitle":"Some title",
    "bodyMessage":"Some message"
  },
    "defaultsecurityrisk":{
    "pageTitle":"Some title",
    "bodyMessage":"Some message"
  },
    "defaultwarning":{
    "pageTitle":"Some title",
    "bodyMessage":"Some message"
  },
    "defaultsecurityrisk":{
    "pageTitle":"Some title",
    "bodyMessage":"Some message"
  },
    "defaultcloudapplication":{
    "pageTitle":"Some title",
    "bodyMessage":"Some message"
  }
}

Updating a specific (nested) attribute in an item can be done using the update_item -method, specifically using an UpdateExpression like this:可以使用update_item方法更新项目中的特定(嵌套)属性,特别是使用如下所示的 UpdateExpression:

SET parent.child =:val
Multiple update attributes can be concatenated in the same fashion.可以以相同的方式连接多个更新属性。

An example on how you could set the title/message on two pages looks like this:关于如何在两个页面上设置标题/消息的示例如下所示:

table.update_item(
        Key={"..": ".."},
        ExpressionAttributeNames={
            "#p": "pages",
            "#blocked": "defaultblocked",
            "#sec": "defaultsecurityrisk",
            "#title": "pageTitle",},
        ExpressionAttributeValues={
            ":val1": "title of blocked page",
            ":val2": "message on blocked page",
            ":val3": "title of security page",
            ":val4": "message on security page",
        },
        UpdateExpression="SET #p.#blocked.#title = :val1, #p.#blocked.#msg = :val2, #p.#sec.#title = :val3, #p.#sec.#msg = :val4",
        ReturnValues="UPDATED_NEW",
    )

Mind the ExpressionAttributeNames and ExpressionAttributeValues .注意ExpressionAttributeNamesExpressionAttributeValues The names always have to start with a # , and the values always start with a : .名称始终必须以#开头,值始终以:开头。 This is a DynamoDB convention to simplify the UpdateExpression, make it easier to read and make it less error prone.这是一个 DynamoDB 约定,用于简化 UpdateExpression,使其更易于阅读并不易出错。

Extending this to include all pages should be trivial, just add the pages to the UpdateExpression and include the values in the ExpressionAttributeNames/Values.扩展它以包含所有页面应该很简单,只需将页面添加到 UpdateExpression 并将值包含在 ExpressionAttributeNames/Values 中。


Edit :编辑
One caveat of this approach, is that you can only update items of a map that already exist.这种方法的一个警告是,您只能更新已经存在的 map 的项目。 For your case, if the existing item does not have a specific page yet, it cannot be updated like this.对于您的情况,如果现有项目还没有特定页面,则无法像这样更新。

To add a new page inside the object, you have to specify the entire object as a value:要在 object 中添加新页面,您必须将整个 object 指定为值:

table.update_item(
    Key={...},
    ExpressionAttributeNames={
        "#p": "pages",
        "#blocked": "defaultblocked",
        "#sec": "defaultsecurityrisk",
        "#title": "pageTitle",
        "#msg": "bodyMessage",
        "#new": "newpage"
    },
    ExpressionAttributeValues={
        ":val1": "title of blocked page",
        ":val2": "message on blocked page",
        ":val3": "title of security page",
        ":val4": "message on security page",
        ":new": {"pageTitle": "new title", "bodyMessage": "page of new body"}
    },
    UpdateExpression="SET #p.#new = :new, #p.#blocked.#title = :val1, #p.#blocked.#msg = :val2, #p.#sec.#title = :val3, #p.#sec.#msg = :val4",
    ReturnValues="UPDATED_NEW",
)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM