Dynamodb返回项的节点或字符串格式错误

2024-06-16 09:44:30 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直在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']

但是,我不想失去这个领域。我不知道如何解决这个问题


Tags: 函数awsjsonfalse示例returnif错误
1条回答
网友
1楼 · 发布于 2024-06-16 09:44:30

问题是,您正在将Python对象转换为JSON字符串(即json.dumps命令),然后尝试将该字符串解释为Python字典(该ast.literal_eval获取一个字符串并尝试将其作为Python代码运行)

python字典看起来非常类似于JSON对象,但它们不是100%兼容的。在JSON中,布尔值表示为truefalse,在Python中表示为TrueFalse

解决这个问题的方法是使用json.loads读取JSON字符串并将其转换为Python等价物:

d = json.loads((json.dumps(i, cls=DecimalEncoder)))

这就是说,将Decimal类转换为本机浮点数似乎需要很多技巧/处理,如果需要将它们传递给需要浮点数的对象,建议直接使用Decimal或转换为浮点数(即float(d['RecordType'])

相关问题 更多 >