【问题标题】:Storing List of Dict in a DynamoDB Table在 DynamoDB 表中存储字典列表
【发布时间】:2019-12-20 23:48:25
【问题描述】:

我想在 DynamoDB 中存储 Elasticsearch 域的标签列表,但遇到了一些错误。

我正在使用 list_tags() 函数获取标签列表: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/es.html#ElasticsearchService.Client.list_tags

response = client.list_tags(
    ARN='string'
)

它返回:

{
    'TagList': [
        {
            'Key': 'string',
            'Value': 'string'
        },
    ]
}

这是他们在文档中所说的: 响应结构

(字典) -- ListTags 操作的结果。包含所有请求的 Elasticsearch 域的标签。 标记列表(列表)-- 请求的 Elasticsearch 域的标签列表。 (字典)—— 为资源标签指定一个键值对。

现在我尝试使用各种方式在 DynamoDB 中插入列表,但我总是遇到错误:

 ':TagList': {
                'M': response_list_tags['TagList']
            },

参数 ExpressionAttributeValues 的类型无效。:TagList.M, value: [{'Key': 'Automation', 'Value': 'None'}, {'Key': 'Owner', 'Value': 'owner '}, {'Key': 'BU', 'Value': 'DS'}, {'Key': 'Support', 'Value': 'teamA'}, {'Key': 'Note', 'Value' ': ''}, {'Key': 'Environment', 'Value': 'dev'}, {'Key': 'Creator', 'Value': ''}, {'Key': 'SubProject', 'Value': ''}, {'Key': 'DateTimeTag', 'Value': 'nodef'}, {'Key': 'ApplicationCode', 'Value': ''}, {'Key': '批评', 'Value': '3'}, {'Key': 'Name', 'Value': 'dev'}], 类型: , 有效类型: : ParamValidationError

尝试使用 L 而不是 M 并得到了这个:

ExpressionAttributeValues 中的未知参数.:TagList.L[11]: "Value", 必须是以下之一:S, N, B, SS, NS, BS, M, L, NULL, BOOL: ParamValidationError

【问题讨论】:

    标签: python amazon-web-services elasticsearch amazon-dynamodb


    【解决方案1】:

    您遇到的具体错误是因为您使用的是本机 DynamoDB 文档项 JSON 格式,该格式要求任何属性值(包括映射中的键值,嵌套在列表中)都必须完全限定类型为键值。

    有两种方法可以做到这一点,根据您的问题,我不确定您是想将这些键值标签对象存储为列表,还是将其存储为 Dynamo 中的实际地图。

    无论哪种方式,我都建议您对列表进行 JSON 编码,并将其作为字符串值存储在 DynamoDB 中。没有很好的理由让您费力将其存储为地图或列表。

    但是,如果您真的愿意,可以转换为 DynamoDB 原生 JSON 并存储为地图。你最终会得到这样的结果:

     ':TagList': {
          'M': {
             'Automation': { 'S': 'None' },
             'Owner': {'S': 'owner'},
             'BU': {'S': 'DS'},
             'Support': {'S': 'teamA'}
                    ...  
          }
      }
    

    另一种可能性是使用地图列表:

      ':TagList': {
          'L': [
             'M': {'Key': {'S': 'Automation'}, 'Value': { 'S': 'None' }},
             'M': {'Key': {'S': 'Owner'}, 'Value' : {'S': 'owner'}},
             'M': {'Key': {'S': 'BU'}, 'Value': {'S': 'DS'}},
             'M': {'Key': {'S': 'Support'}, 'Value': {'S': 'teamA'}}
                    ...  
          ]
      }
    

    但根据我的经验,我从来没有从在 Dynamo 中存储这样的数据中获得任何真正的价值。相反,将这些标签存储为 JSON 字符串既简单又不易出错。你最终会得到这个:

      ':TagList': {
          'S': '{\'Key\': \'Automation\', \'Value\': \'None\'}, {\'Key\': \'Owner\', \'Value\': \'owner\'}, {\'Key\': \'BU\', \'Value\': \'DS\'}, {\'Key\': \'Support\', \'Value\': \'teamA\'}, ... }'
      }
    

    你所要做的就是扭动相当于:

     ':TagList': {
         'S': json.dumps(response_list_tags['TagList'])
     }
    

    【讨论】:

      【解决方案2】:

      谢谢迈克,我找到了类似的解决方案。我将标签列表存储为这样的字符串:

      ':TagList': {
         'S': str(response_list_tags['TagList'])
      }
      

      然后将字符串转换为列表以供以后使用,我这样做了:

      import ast
      ...
      TagList= ast.literal_eval(db_result['Item']['TagList']['S'])
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多