我一直在AWS中试验DynamoDB,并认为它对我来说是错误的工具。在AWS中工作时,我向系统上传了大量记录,我现在正试图使用Python检索这些记录。我承认,我对Python完全是新手,我所拼凑的是从互联网上找到的示例。我正在使用Office 365审核日志,这些日志包含许多字段,当我从Dynamo检索它们时,我发现十进制字段返回为decimal('1')
{
'ItemType': 'File',
'SourceFileName': 'xxx',
'UserKey': 'xxx',
'RecordType': Decimal('6'),
'UserId': 'xxx',
'ClientIP': 'xxx',
'CorrelationId': 'xxx',
'ObjectId': 'xxx',
'Version': Decimal('1'),
'Site': 'xxx',
'WebId': 'xxx',
'SourceFileExtension': 'js',
'SiteUrl': 'xxx',
'Workload': 'SharePoint',
'SourceRelativeUrl': 'xxx',
'EventSource': 'SharePoint',
'ListId': 'xxx',
'OrganizationId': 'xxx',
'Operation': 'FileAccessed',
'UserAgent': 'xxx',
'ListItemUniqueId': 'xxx',
'CreationTime': '2019-07-26T21:54:45',
'UserType': Decimal('0'),
'Id': 'xxx',
'CustomUniqueId': False
}
在疑难解答中,我发现了这个方便的函数,它可以将十进制('0')转换为实际的十进制
class DecimalEncoder(json.JSONEncoder):
def default(self, o):
if isinstance(o, decimal.Decimal):
if o % 1 > 0:
return float(o)
else:
return int(o)
return super(DecimalEncoder, self).default(o)
这个函数叫做
response = table.scan(Limit=10)
for i in response['Items']:
d = ast.literal_eval((json.dumps(i, cls=DecimalEncoder)))
在大多数情况下,这很好,除非我有一个布尔字段(如上面的示例)。然后我得到了这个错误
malformed node or string: <_ast.Name object at 0x04B3F778>
据我对Python的理解,True和False的布尔值是正确大写的。。我考虑添加DecimalEncoder默认方法,但这不会有多大作用,因为它实际上返回相同的值
elif isinstance(o,bool):
return True if o else False
我确实找到了钥匙,但没有出错
if 'CustomUniqueId' in i:
del i['CustomUniqueId']
但是,我不想失去这个领域。我不知道如何解决这个问题
问题是,您正在将Python对象转换为JSON字符串(即
json.dumps
命令),然后尝试将该字符串解释为Python字典(该ast.literal_eval
获取一个字符串并尝试将其作为Python代码运行)python字典看起来非常类似于JSON对象,但它们不是100%兼容的。在JSON中,布尔值表示为
true
和false
,在Python中表示为True
和False
解决这个问题的方法是使用
json.loads
读取JSON字符串并将其转换为Python等价物:这就是说,将Decimal类转换为本机浮点数似乎需要很多技巧/处理,如果需要将它们传递给需要浮点数的对象,建议直接使用Decimal或转换为浮点数(即
float(d['RecordType'])
)相关问题 更多 >
编程相关推荐