我正在使用Python查询API,此API发送最后X个事件的JSON,我想保留它发送给我的历史记录。
这就是API发送的内容,我的平面历史文件中有相同类型的元素(但是有更多相同的对象)。 API和我的最终文件没有用于设置字典的密钥。
[{
"Item1": "01234",
"Item2": "Company",
"Item3": "XXXXXXXXX",
"Item4": "",
"Item5": "2015-12-17T12:00:01.553",
"Item6": "2015-12-18T12:00:00"
},
{
"Item1": "01234",
"Item2": "Company2",
"Item3": "XXXXXXX",
"Item4": null,
"Item5": "2015-12-17T16:49:23.76",
"Item6": "2015-12-18T11:00:00",
}]
如果API的元素不在原始文件中,我该如何添加? 我有一个打开/关闭文件的框架,但对处理没有太多想法。
main_file=open("History.json","r")
new_items=[]
api_data=requests.get(#here lies the api address and the header)
#here should be the deplucation/processing process
for item in api_data
if item not in main_file
new_items.append(item)
main_file.close()
try:
file_updated = open("History.json",'w')
file_updated.write(new_items + main_file)
file_updated.close()
print("File updated")
except :
print("Error writing file")
编辑:我使用json对象方法来执行此操作:
from collections import namedtuple
Event = namedtuple('Event', 'Item1, Item2, Item3, Item4, Item5, Item6')
def parse_json_events(text):
events = [ Event(**k) for k in json.loads(text) ]
return events
if path.exists('Mainfile.json'):
with open('Mainfile.json') as data_file:
local_data = json.load(data_file)
print(local_data.text) #debug purposes
events_local=parse_json_events(local_data.text)
else:
events_local=[]
events_api=parse_json_events(api_request.text)
inserted_events=0
for e in events_api[::-1]:
if e not in events_local:
events_local.insert(0, e)
inserted_events=inserted_events+1
print("inserted elements %d" % inserted_events)
print(events_local) # this is OK, gives me a list of events
print(json.dump(events_local)) # this ... well... I want the list of object to be serialized but I get this error :
TypeError:dump()缺少1个必需的位置参数:'fp'
答案 0 :(得分:1)
我认为解决这个问题的最佳方法是考虑您的数据结构。看起来你现在正在使用与api相同的数据结构。
这些项目字段中是否有Id
?如果是,请使用该字段进行重复数据删除。但是对于这个例子,我将使用公司名称。
with open('history.json') as f:
historic_data = json.load(f)
api_data = requests.get()
for item in api_data:
historic_data[item['Item2']] = item
f.write(json.dumps(historic_data))
每次本例中的名称已经存在于字典中时,它将被覆盖。如果该名称不存在,则会添加该名称。
答案 1 :(得分:1)
通常,您可以通过使用/不使用第三方工具(如Avro,Thrift等)定义架构来解决此类问题。基本上,您从API获得的每条记录都需要使用您正在使用的编程语言转换为实体。
我们以此JSON对象为例:
{
"Item1": "01234",
"Item2": "Company",
"Item3": "XXXXXXXXX",
"Item4": "",
"Item5": "2015-12-17T12:00:01.553",
"Item6": "2015-12-18T12:00:00"
},
如果您有类似
的架构Company(object):
company_number = ...
name = ...
# other fields
然后,您需要做的就是序列化和反序列化原始数据。
理想情况下,您从API中读取JSON响应,然后您可以简单地将每个json对象拆分为架构对象(使用或不使用工具)。在伪代码中:
api_client = client(http://..., )
response = api_client.get("/resources")
json = response.json
companies = parse_json_companies(json) # list of Company objects
此时,处理从api获取的数据非常容易。您应该对存储在文件系统中的文件执行相同的操作。加载文件并反序列化记录(到公司对象)。然后,比较对象将很容易,因为它们将像“普通”Python对象,因此您可以执行比较等。
例如:
from collections import namedtuple
import json
Company = namedtuple('Company', 'Item1, Item2, Item3, Item4, Item5, Item6')
def parse_json_companies(text):
companies = [Company(**k) for k in json.loads(text)]
return companies
>>> companies = parse_json_companies(response.json)
>>> companies
[Company(Item1='01234', Item2='Company', Item3='XXXXXXXXX', Item4=u'', Item5='2015-12-17T12:00:01.553', Item6='2015-12-18T12:00:00'), Company(Item1='01234', Item2='Company2', Item3='XXXXXXX', Item4=None, Item5='2015-12-17T16:49:23.76', Item6='2015-12-18T11:00:00')]
.dump(obj,fp)错误后更新。
如果您使用json.dump收到错误,请参阅documentation。它明确指出 obj 和 fp 是必需的参数。
使用此转换表将obj作为JSON格式的流序列化为fp(.write() - 支持类似文件的对象)。
因此,您需要传递支持.write的对象(例如,以写入模式打开的文件)。