python json对比差异,更新json数据

  在使用常见的第三方库(deepdiff、json_tools、jsonpatch)获取两个json对象的差异后,如何根据差异,对json对象进行修改。如何从对比结果中获取数据的key是问题的关键。

  deepdiff举例:

from deepdiff import DeepDiff

a = {"name": "yanan", "pro": {"sh": "shandong", "city": ["zibo", "weifang"]}}
b = {"name": "Yanan", "pro": {"sh": "shandong", "town": ["taian", "weifang"]}}

result = DeepDiff(a, b)

print(result)
{'dictionary_item_added': [root['pro']['town']], 'dictionary_item_removed': [root['pro']['city']], 'values_changed': {"root['name']": {'new_value': 'Yanan', 'old_value': 'yanan'}}}
  • 增加了一个item对象:b['pro']['town']
  • 移除了一个item对象:a['pro']['city']
  • 数据发生改变的有:a['name'] 变为 b['name']

deepdiff库中,可以

  1. 使用_path_to_elements方法实现将root['name']转换为(('name', 'GET'),)
    deepdiff.path._path_to_elements("root['name']", root_element=None)
    
  2. 然后使_get_nested_obj用获取原对象中对应的数据。
    deepdiff.path._get_nested_obj(b,(('name', 'GET'),))
    

在我的使用场景中,只关心对象的类型、数据是否发生改变,其他item对象的增加、删除并不关心。所以最终的实现的代码如下,大家可以根据自己的具体应用场景进行修改:

from deepdiff import DeepDiff
from deepdiff.path import _path_to_elements, _get_nested_obj


def update_json(new_json, old_json=None):
	# 更新 json 文件
	if not old_json:
		return new_json

	diff_obj = DeepDiff(old_json, new_json, verbose_level=2)

	if diff_obj.get('type_changes'):
		for _path, item in diff_obj['type_changes'].items():
			if (isinstance(item['new_value'], list) or isinstance(item['new_value'], dict) \
			    or isinstance(item['new_value'], str)) and len(item['new_value']) == 0:
				continue
			cur_node = _path_to_elements(_path, root_element=None)
			parent_node = _get_nested_obj(old_json, cur_node[:-1])
			parent_node[cur_node[-1][0]] = item['new_value']

	if diff_obj.get('values_changed'):
		for _path, item in diff_obj['values_changed'].items():
			cur_node = _path_to_elements(_path, root_element=None)
			parent_node = _get_nested_obj(old_json, cur_node[:-1])
			parent_node[cur_node[-1][0]] = item['new_value']
	return old_json
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值