【问题标题】:Inserting None values into DynamoDB using Boto使用 Boto 将 None 值插入 DynamoDB
【发布时间】:2020-10-07 14:26:12
【问题描述】:

我是 Boto 的新手,我正在尝试使用它将 Python 字典插入 Amazon DynamoDB。我一定遗漏了一些东西,因为“dynamizer”(编码器)似乎不支持 None 值。这是一个问题,因为源数据中有大量的空值。我可以遍历每一行并删除值为 None 的所有键/值项,但不知何故,我觉得像 Boto 这样复杂的包应该为我处理好。我只是想像这样插入一行:

conn = DynamoDBConnection(region=RegionInfo(endpoint="dynamodb.us-west-2.amazonaws.com"))
dest = Table('d_company', connection=conn)
data = {"company_id":99999, "company_name":None}
dest.put_item(data)

...这给了我错误:

Error
Traceback (most recent call last):
  File "TestDynamoDB.py", line 37, in testPutIntoDynamoDB
    dest.put_item(data)
  File "C:\Python27\lib\site-packages\boto\dynamodb2\table.py", line 452, in put_item
    return item.save(overwrite=overwrite)
  File "C:\Python27\lib\site-packages\boto\dynamodb2\items.py", line 362, in save
    final_data = self.prepare_full()
  File "C:\Python27\lib\site-packages\boto\dynamodb2\items.py", line 265, in prepare_full
    final_data[key] = self._dynamizer.encode(value)
  File "C:\Python27\lib\site-packages\boto\dynamodb\types.py", line 228, in encode
    dynamodb_type = self._get_dynamodb_type(attr)
  File "C:\Python27\lib\site-packages\boto\dynamodb\types.py", line 220, in _get_dynamodb_type
    return get_dynamodb_type(attr)
  File "C:\Python27\lib\site-packages\boto\dynamodb\types.py", line 110, in get_dynamodb_type
    raise TypeError(msg)
TypeError: Unsupported type "<type 'NoneType'>" for value "None"

我做错了什么?

【问题讨论】:

    标签: python nosql boto amazon-dynamodb


    【解决方案1】:

    DynamoDB 中的属性值既不能是空字符串,也不能是空集。虽然我凭经验发现了这一点,但我看到的最直接的参考是这里:

    http://awsdocs.s3.amazonaws.com/dynamodb/latest/dynamodb-dg.pdf

    因此,批准的答案建议的第二个项目符号将不起作用。

    已接受答案的第三个项目符号是最佳方法,正如已接受答案所暗示的那样。从设计的角度来看,它更接近于 NoSql 范式,并且可能会提供某种程度的效率,而不是尝试为每种数据类型识别 None/NULL 表示并存储它。然后,此范例在您的逻辑中表现为检查键的存在/成员资格(if/then 或 try/except,具体取决于场景),而不是检查键的“None/NULL 等效”值。

    如果你真的想用你等同于 NULL/None 的值来存储属性,我建议在你的应用程序中建立一个唯一/专有的值来实现这一点,这比在字符串的情况下更容易识别,只是“无”。

    (我宁愿简单地评论现有的答案,但我作为 stackoverflow 的新用户的身份显然阻止了我这样做......希望这不是糟糕的礼仪......)

    【讨论】:

      【解决方案2】:

      你没有做错任何事。虽然boto 确实很复杂,但您必须记住,它不了解您的业务逻辑。

      例如,至少有几种方法可以考虑将None 保存到 DynamoDB 数据库:

      • 作为“无”字符串
      • 作为空字符串
      • 根本不保存 - 记住,它是 NoSQL 数据库,不需要属性

      确定它的最佳方法是您的代码。如果您的数据可能是None,请不要将其添加到字典中。

      【讨论】:

      • 我希望有一个与此不同的解决方案,正如我已经建议的那样。但是,由于没有其他人回复,我想我会将其标记为正确答案。谢谢。
      • DynamoDB 不允许存储空字符串。
      【解决方案3】:

      更新 - 2020 年 5 月
      AWS 更新DynamoDB supports Null and empty objects

      根据这次更新 -

      Amazon DynamoDB 现在支持 DynamoDB 表中非键字符串和二进制属性的空值。空值支持使您可以更灵活地将属性用于更广泛的用例集,而无需在将这些属性发送到 DynamoDB 之前对其进行转换。 List、Map 和 Set 数据类型也支持空字符串和二进制值。

      基表的分区键和排序键属性继续要求所有数据类型(包括字符串和二进制)的非空值。同样,本地二级索引或全局二级索引的String和Binary键属性也需要非空值。

      要放置空属性,请使用“NULL”类型并将值设置为 True。

      PythonAttributeUpdates["MyNull"] = {'Value': {'NULL': True}, 'Action': 'PUT'}

      要放置空字符串属性,请使用类型“S”和值作为“”。

      PythonAttributeUpdates["MyEmptyString"] = {'Value': {'S': ""}, 'Action': 'PUT'}

      这将是一个有效的 dynamoDB put_item 负载。 更多详情 - API_PutItem

      【讨论】:

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