有没有办法在将从某个端点接收到的 json 插入到 DynamoDB 之前,在任意位置填充空字符串(不知道 json 的结构)?众所周知,它存在浮点数问题,您必须将它们转换为小数,但似乎无法找到一种简单的方法来填充空字符串,例如“full_name”:“”,其值类似于“N/A” .
我正在寻找类似 json.loads(json.dumps(data), parse_float=Decimal) 的东西,对于 parse_float 的东西,但对于空字符串。干净且易于使用的东西。我已经看到您可以为此使用自定义 cls 类,但我不太明白如何正确执行此操作,尤其是在不知道可能会有所不同的 json 结构的情况下。
JSON 示例:
{
"campaign_id": "9c1c6cd7-fd4d-480b-8c80-07091cdd4103",
"creation_date": 1530804132,
"objects": [
{
"id": 12345,
"full_name": ""
},
...
],
...
}
您可以通过定义一个 object_hook 传递给
json.loads
来完成此操作。
来自文档:
object_hook 是一个可选函数,将使用任何对象文字解码(字典)的结果来调用。将使用 object_hook 的返回值代替字典。
鉴于此命令:
>>> pprint(d)
{'campaign_id': '9c1c6cd7-fd4d-480b-8c80-07091cdd4103',
'creation_date': 1530804132,
'float': 1.2345,
'objects': [{'full_name': '', 'id': 12345}],
'strs': ['', 'abc', {'a': ''}],
'top_str': ''}
这对函数将递归
json.loads
的结果,并将空字符串的实例更改为“N/A”。
def transform_dict(mapping=None):
if mapping is None:
mapping = {}
for k, v in mapping.items():
if v == '':
mapping[k] = 'N/A'
elif isinstance(v, dict):
mapping[k] = transform_dict(v)
elif isinstance(v, list):
mapping[k] = transform_list(v)
else:
# Make it obvious that we aren't changing other values
pass
return mapping
def transform_list(lst):
for i, x in enumerate(lst):
if x == '':
lst[i] = 'N/A'
elif isinstance(x, dict):
lst[i] = transform_dict(x)
elif isinstance(x, list):
lst[i] = transform_list(x)
else:
# Make it obvious that we aren't changing other values
pass
return lst
>>> res = json.loads(
json.dumps(d),
parse_float=decimal.Decimal,
object_hook=transform_dict,
)
>>> pprint(res)
{'campaign_id': '9c1c6cd7-fd4d-480b-8c80-07091cdd4103',
'creation_date': 1530804132,
'float': Decimal('1.2345'),
'objects': [{'full_name': 'N/A', 'id': 12345}],
'strs': ['N/A', 'abc', {'a': 'N/A'}],
'top_str': 'N/A'}
请注意,此方法取决于输入 json 是 json 对象 (
{...}
)。