Reputation: 25
Expecting
I am expecting to create/add new record and load json files using python.
Json Result
{
"2313213": [
{
"_aliasinput": "2313213",
"_idinput": "321",
"_timesinput": []
}
]
}{
"321312312": [
{
"_aliasinput": "321312312",
"_idinput": "534342",
"_timesinput": []
}
]
}{
"31232131": [
{
"_aliasinput": "31232131",
"_idinput": "3123129312",
"_timesinput": [
"10:29"
]
}
]
}
I m not sure if JSON is well formatted. Maybe should it be any error when creating this file? What is the best and correct thing to do on this case? i expect return and print that values on terminal on this project that's why i need to understand what is wrong on this code. As you can see i have a input with a list of values. Hope you could me help on that.
Error:
First time it works well, but 2nd time get the error below, seems that json it not created correct.
json.decoder.JSONDecodeError: Extra data: line 9 column 2 (char 145)
Any idea where is my error? Hope you help me on this issue.
Code to create json
import os
import json
alias_input = input("Alias input:\n:> ")
id_input = input("ID input:\n:> ")
times_input = [item for item in input("Times input:\n:> ").split()]
def save():
filename = "config"
if filename == "":
print("Insert a profile name")
else:
line = [dict(_aliasinput=alias_input, _idinput=id_input, _timesinput=times_input)]
line_save = { alias_input : line }
profile = open('config'+filename+'.json', 'w')
if not os.path.exists('config'):
os.makedirs('config')
with open('config/'+filename+'.json', 'a') as outfile:
json.dump(line_save, outfile, indent=4, sort_keys=False)
profile.close()
print("Profile", filename, "is saved.")
save()
Code to load json
import os
import json
alias_input2 = input("Alias input:\n:> ")
def load():
filename = "config.json"
if filename == "":
print("Insert a profile name")
else:
with open('config/'+'config'+'.json', 'r') as outfile:
data = json.load(outfile)
for element in data[alias_input2]:
alias_input = (element['_aliasinput'])
id_input = (element['_idinput'])
times_input = (element['_timesinput'])
position = 0
position += 1
print(f"({position}) Alias input: {alias_input} ID input: {id_input} Times input: {times_input}")
outfile.close()
load()
Upvotes: 0
Views: 350
Reputation: 66
Having a JSON file with multiple entities is not valid, so you have to change your JSON file structure to this:
[
{
"2313213": [
{
"_aliasinput": "2313213",
"_idinput": "321",
"_timesinput": []
}
]
},
{
"321312312": [
{
"_aliasinput": "321312312",
"_idinput": "534342",
"_timesinput": []
}
]
},
{
"31232131": [
{
"_aliasinput": "31232131",
"_idinput": "3123129312",
"_timesinput": [
"10:29"
]
}
]
}
]
a JSON file contains a single entity that can contain multiple objects. so, the code must change to something like this:
loaded_list: list = load_json()
loaded_list.append(create_object())
save_json(loaded_list)
# save_json function must replace the old JSON file with the new one
The problem with your code is the save
function, you save it in an inappropriate format (by using a
switch, you just append a new JSON object to the old one on the file, so it makes it an invalid JSON file), hence when it attempts to load it with json.load
in load
function, it will raise that exception.
your code must change to something like this:
import json
import os
def producer():
return {
"321312312": [
{
"_aliasinput": "321312312",
"_idinput": "534342",
"_timesinput": []
}
]
}
to_write = [producer() for _ in range(10)] # just a faker to reproduce the data
def save():
if not os.path.exists('file.json'):
with open('file.json', 'w') as file:
json.dump([], file) # create an initial json file
with open('file.json', '+r') as file:
previous_data: list = json.load(file) # load previous data, surly we excpect to be a list
file.seek(0)
previous_data.extend(to_write) # add new data to old ones
json.dump(previous_data, file) # replace the extend list to the json file
file.truncate()
def load():
with open('file.json', 'r') as file:
data: list = json.load(file)
return data
Upvotes: 2
Reputation: 54698
A JSON file has to be a single entity: a single list, or a single dict/object. When you append multiple JSON records to a single file, that is no longer a valid JSON file.
You have two choices. In your save
function, you can fetch the old contents (which must be a list), append your new object to that, and rewrite the file. The other choice is to change your reader to read and decode the lines one by one. You can't decode the whole file as it is. So, instead of:
with open('config/'+'config'+'.json', 'r') as outfile:
data = json.load(outfile)
you can try:
data = []
for rec in open(f'config/{config}.json', 'r'):
data.append( json.loads(rec) )
That could be done as a list comprehension, but that's just showing off.
Upvotes: 1