I have some json data source and want to either create an output file and write the first payload to that file, otherwise (if the file already exists) I want to append to it. But I can't seem to do it:
import json
import time
data = {'key1': 1, 'key2': {'k2a': 2.1, 'k2b': 2.2}}
fname = 'test.json'
with open(fname, 'a ') as f:
try:
loaded = json.load(f)
loaded.append({'appended': time.time()})
except json.decoder.JSONDecodeError as e:
print(e)
loaded = [data]
json.dump(loaded, f)
On the first run of that code it creates the json file as expected. However on the second it prints out Expecting value: line 1 column 1 (char 0)
, meaning the try block doesn't correctly execute, and the end result in the file is: [{ "key1": 1, "key2": { "k2a": 2.1, "k2b": 2.2 }}][{"key1": 1, "key2": {"k2a": 2.1, "k2b": 2.2}}]
which is clearly not correct.
I think this is a really convoluted way to accomplish something that must be a very common task, but surely there is a straightforward way? I've looked but many examples just append to pre-existing files.
CodePudding user response:
You cannot append to a json-file as such. See the json file as one (serialized) python object, in your case a dictionary.
You could load the json file (if it's there), and if not initialise it as en empty dict.
Then add the data that you wish and save it again (in one piece).
import json
import time
fname = 'test.json'
loaded = {}
try:
with open(fname, "r") as f:
loaded = json.load(f)
except IOError:
# may complain to user as well
pass
loaded['appended'] = time.time()
with open(fname, "w") as f:
json.dump(loaded, f)
CodePudding user response:
I don't think you can append using json.dump, you'll have to handle it with something like this.
import os
import json
import time
fname = "test.json"
data = {'key1': 1, 'key2': {'k2a': 2.1, 'k2b': 2.2}}
if os.path.exists(fname):
#read existing file and append new data
with open(fname,"r") as f:
loaded = json.load(f)
loaded.append({'appended': time.time()})
else:
#create new json
loaded = [data]
#overwrite/create file
with open(fname,"w") as f:
json.dump(loaded,f)