使用Boto将None值插入DynamoDB

fut*_*bel 9 python boto nosql amazon-dynamodb

我是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)
Run Code Online (Sandbox Code Playgroud)

......这给了我错误:

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"
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

小智 10

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

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

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

公认答案所暗示的是,可接受答案的第三个项目符号是最佳方法。从设计的角度来看,它更符合NoSql范式,并且可能比尝试为每种数据类型标识None / NULL表示并存储它提供某种程度的效率。然后,此范式在您的逻辑中表现为检查密钥的存在/成员身份(if / then或try / except,取决于情况),而不是检查密钥的“ None / NULL等效”值。

如果您确实希望使用等于NULL / None的值来存储属性,那么我建议您为在应用程序中完成此操作而建立一个唯一/专有值,这比字符串的情况更容易识别。 '。

(我宁愿只是对现有答案发表评论,但是我作为stackoverflow的新用户的身份显然阻止了我这样做……希望这不是礼节……)


kuk*_*ido 5

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

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

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

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


小智 5

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

根据此更新 -

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

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

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

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

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

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

这将是有效的 dynamoDB put_item 负载。更多详细信息 - API_PutItem