10

我是 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"

我究竟做错了什么?

4

3 回答 3

12

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

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

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

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

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

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

于 2015-07-13T21:41:30.797 回答
9

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

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

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

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

于 2014-01-16T07:39:25.380 回答
1

更新 - 2020 年 5 月
AWS 更新DynamoDB 支持 Null 和空对象

根据此更新 -

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

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

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

蟒蛇AttributeUpdates["MyNull"] = {'Value': {'NULL': True}, 'Action': 'PUT'}

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

蟒蛇AttributeUpdates["MyEmptyString"] = {'Value': {'S': ""}, 'Action': 'PUT'}

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

于 2020-10-07T06:26:12.423 回答