8-Bit Borges
8-Bit Borges

Reputation: 10033

Python - update item in an existing json file

I want to update float values inside my json file, structured like this:

{"Starbucks": {"Roads": 1.0, "Pyramid Song": 1.0, "Go It Alone": 1.0}}

So whenever I generate an already existing playlist, with the exact same items, I increment key values by +1.0.

I have a file opened with 'append' option

with open('pre_database/playlist.json', 'a') as f:
     if os.path.exists('pre_database/playlist.json'):
         #update json here
     json.dump(playlist,f)

but this 'a' method would append another dictionary to json, and it would generate parsing problems later on.

likewise, if I use 'w' method, it would overwrite the file entirely.

what is the best solution for updating the values?

Upvotes: 1

Views: 12658

Answers (3)

Rohit
Rohit

Reputation: 632

It is appendind new dictionary because file is opened in append mode and cursor is at end of file. You need to truncate before dumping latest dict to file

with open('pre_database/playlist.json', 'a') as f:
    if os.path.exists('pre_database/playlist.json'):
        f.seek(0)
        playlist = json.load(f)
        #Update your dict here
        playlist.update(dict({'key1':'NewValue1'}))
        f.truncate(0)
        playlist.dump(playlist,f)

Upvotes: 0

Robin Koch
Robin Koch

Reputation: 726

Appending means that your file is getting longer, which is neither what you what nor how JSON works.

If you want to update some value you need to load the json-file, update your value(s) and dump it back:

with open('pre_database/playlist.json', 'r') as f:
    playlist = json.load(f)
playlist[key] = value  # or whatever
with open('pre_database/playlist.json', 'w') as f:
    json.dump(playlist, f)

Also your check if your file exists should happen before you open the file and not when it's already open:

if os.path.exists('pre_database/playlist.json'):
    with open('pre_database/playlist.json', 'r') as f:
        playlist = json.load(f)
    playlist[key] = value  # or whatever
    with open('pre_database/playlist.json', 'w') as f:
        json.dump(playlist, f)

although I guess the pythonic ways would be to just try it and catch the IOError if the file didn't exist as expected.

Depending on how you continue it's probably best to do something like this:

try:
    with open('pre_database/playlist.json', 'r') as f:
        playlist = json.load(f)
except IOError, ValueError:
    playlist = default_playlist

playlist[key] = value  # or whatever

with open('pre_database/playlist.json', 'w') as f:
    json.dump(playlist, f)

Robin

Upvotes: 2

Moses Koledoye
Moses Koledoye

Reputation: 78546

You could open the file in r+ mode (opens the file for both reading and writing), read in the JSON content, seek back to the start of the file, truncate it and then rewrite the modified dictionary back to the file:

if os.path.exists('pre_database/playlist.json'):
    with open('pre_database/playlist.json', 'r+') as f:
         playlist = json.load(f)
         # update json here
         f.seek(0)
         f.truncate()
         json.dump(playlist, f)

Upvotes: 5

Related Questions