aws DynamoDB Cli - использование JQ на вложенных json - PullRequest
0 голосов
/ 24 февраля 2020

Мне нужно поменять значение в записи DynamoDB. Трудность заключается в том, что коллега, который составил таблицу, использовал вложенную json в поле, которое мне нужно отредактировать. У меня проблемы с выяснением того, как редактировать значение, когда макет асимметричный.

Допустим, строка в DynamoDB выглядит так с get-item:

{    
 "Item": {
      "aws:rep:deleting": {
        "BOOL": false
      },
      "service": {
        "S": "g"
      },
      "settings": {
        "L": [
          {
            "M": {
              "fe_enabled": {
                "BOOL": false
              },
              "stack_type": {
                "S": "all"
              },
              "label": {
                "S": "helm_chart_name"
              },
              "value": {
                "S": "gate"
              }
            }
          },
          {
            "M": {
              "fe_enabled": {
                "BOOL": true
              },
              "stack_type": {
                "S": "all"
              },
              "label": {
                "S": "helm_chart_version"
              },
              "value": {
                "S": "0.1.1"
              }
            }
          }
        ]
      },
      "label": {
        "S": "gate"
      },
      "service_children": {
        "L": []
      },
      "independent": {
        "BOOL": true
      }
    }
}

Мне нужно изменить значение helm_chart_version на - скажем - 0.1.2.

Я начал с попытки выделить значение. Я безуспешно пробовал следующие варианты:

jq -r '.Item[].L.M | select(.label == "helm_4G_chart_version") | .value.S'
#  errors because there are multiple L's so it's iterating over null

jq '..|.label? | select(type != "null")'
#  discovered this neat syntax, but I can't figure out how to get value from that

jq --arg argName "argValue" '()' file.json | sponge file.json
#  this is likely the "replace" solution, but I don't know what to put in the () to get the right value

Также открыта возможность услышать, что я занимаюсь этим неправильно - я немного не в себе. Я планирую сохранить отредактированный файл json в файл, а затем выполнить наложение элемента. Это правильный способ редактировать запись в DynamoDB?

Ответы [ 2 ]

1 голос
/ 24 февраля 2020

Если вы хотите обойти отдельные объекты и найти объект для обновления и установить его значение, вы можете сделать

jq '(.Item.settings.L[] | select(.M.label.S == "helm_chart_version")) |= (.M.value.S = "0.1.2")'

часть перед |=, которая идентифицирует правильный объект, соответствующий вашей строке , Как только объект идентифицирован, оператор обновления |= просто изменяет поле с требуемым значением. Посмотрите, как работает jq-play

0 голосов
/ 24 февраля 2020

Если удобство дорого, то использование walk может многое порекомендовать:

walk(if type == "object" and .label.S == "helm_chart_version"
     then .value.S = "0.1.2" else . end)

Это, конечно, предполагает, что "S" известно заранее. Если это не так, то одной из возможностей для рассмотрения будет:

walk(if type == "object" and has("label") and any(.label[]; . == "helm_chart_version") 
     then .value |= map_values("0.1.2") else . end)

Вариации

Если вы не хотите walk весь объект, вы можете просто пройти .settings:

.Item.settings
|= walk(if type == "object" 
        and has("label")
        and any(.label[]; . == "helm_chart_version")
        then .value |= map_values("0.1.2")
        else . 
        end)

Или, если «метка» также неизвестна:

.Item.settings
|= (. as $in
    | [paths
       | . as $p
       | select(($in|getpath($p)) == "helm_chart_version")]
    | reduce .[] as $p ($in; setpath($p | (.[-2] = "value"); "0.1.2")))
...