【问题标题】:Multi-valued data in DynamoDB using botoDynamoDB 中使用 boto 的多值数据
【发布时间】:2019-05-02 08:49:46
【问题描述】:

在浏览了文档和各种教程之后,我无法弄清楚如何设置或更新作为多值数据类型(数字或字符串集)的发电机项的属性。我正在使用 boto(具体来说是 boto.dynamodb2 ——不是 boto.dynamodb)。

尝试这样的事情(其中 'id' 是哈希键):

Item(Table('test'), data={'id': '123', 'content': 'test', 'list': [1,2,3,4]}).save()

导致此错误:

TypeError: Unsupported type "<type 'list'>" for value "[1, 2, 3, 4]"

我觉得这在 boto.dynamodb2 中一定是可能的,但奇怪的是我找不到任何人这样做的例子。 (大家只是设置数字或字符串属性,而不是数字集或字符串集属性。)

非常感谢您对此主题的任何见解以及我如何使其与 boto 一起使用!我猜我忽略了一些简单的事情。谢谢!

【问题讨论】:

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


    【解决方案1】:

    好的,我们能够自己解决这个问题。我上面示例的问题是我使用的是列表而不是集合。多值属性的值必须是一个集合。

    例如,这是有效的:

    Item(Table('test'), data={'id': '123', 'content': 'test', 'list': set([1,2,3,4])}).save()
    

    【讨论】:

    • 感谢您指出这一点!不幸的是,这限制了 DynamoDB 中多值属性的使用,因为 set() 不能多次具有相同的值。这对于标签之类的东西是可以的,但它不适用于任意数值的列表。
    • 快速问题:你知道 1) 是否可以将列表以外的其他类型转换为集合(例如:dict/map)2) 具有嵌套值,假设 #1 是可行的?根据this,应该可以有一个dicts列表,但我们不能让它工作。
    【解决方案2】:

    DnyamoDB 现在直接支持 Dict/List。 Boto 尚不支持它,但它只是一个小补丁,直到它在生产中得到支持。

    ############################################################
    # Patch Dynamizer to support dict/list
    ############################################################
    from boto.dynamodb.types import Dynamizer, get_dynamodb_type
    
    def _get_dynamodb_type(self, attr):
      if isinstance(attr, dict):
        return 'M'
      if isinstance(attr, list):
        return 'L'
      return get_dynamodb_type(attr)
    
    def _encode_m(self, attr):
      result = {}
      for k, v in attr.items():
        result[k] = self.encode(v)
      return result
    
    def _decode_m(self, attr):
      result = {}
      for k, v in attr.items():
        result[k] = self.decode(v)
      return result
    
    def _encode_l(self, attr):
      return [self.encode(v) for v in attr]
    
    def _decode_l(self, attr):
      return [self.decode(v) for v in attr]
    
    Dynamizer._get_dynamodb_type = _get_dynamodb_type
    Dynamizer._encode_m = _encode_m
    Dynamizer._decode_m = _decode_m
    Dynamizer._encode_l = _encode_l
    Dynamizer._decode_l = _decode_l
    ############################################################
    # End patch Dynamizer to support dict/list
    ############################################################
    

    【讨论】:

    • 现在或多或少在 boto 中。
    • Gary Linscott:您知道目前(2015 年 4 月)Boto 是否支持 dynamodb map 数据类型,更一般地,将 JSON 文档存储为项目属性的值?在哪里可以找到这方面的信息?
    • Boto v2.35.2 现在支持maplistgithub.com/boto/boto/issues/2737 虽然我没能找到很棒的文档...
    【解决方案3】:

    这与boto3 正常工作:

    session = boto3.Session(
    aws_access_key_id=AWS_ACCESS_KEY_ID,
    aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
    )
    
    dynamodb = session.resource('dynamodb', region_name='us-east-1')
    table = dynamodb.Table('table')
    
    list = ['1','2','3'] 
    
    table.put_item(
        Item={
            'id': 01,
            'message': list,
            'timestamp': '2019-05-01 22:14:00'
        }
    )
    

    您的数据将按如下方式保存:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-04-06
      • 2021-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多