0

I am trying to append values to a json file. How can i append the data? I have been trying so many ways but none are working ?

Code:

def all(title,author,body,type):

    title = "hello"
    author = "njas"
    body = "vgbhn"
    data = {
            "id" : id,
            "author": author,
            "body" : body,
            "title" : title,
            "type" : type
           }

    data_json = json.dumps(data)
    #data = ast.literal_eval(data)
    #print data_json
    if(os.path.isfile("offline_post.json")):
        with open('offline_post.json','a') as f:
            new = json.loads(f)
            new.update(a_dict)
            json.dump(new,f)
    else:
        open('offline_post.json', 'a')
        with open('offline_post.json','a') as f:
            new = json.loads(f)
            new.update(a_dict)
            json.dump(new,f)

How can I append data to json file when this function is called?

J Richard Snape
  • 20,116
  • 5
  • 51
  • 79
TorreZz
  • 115
  • 10
  • 2
    Can you expand a bit on what's not working? Are you getting an error? – glibdud Jan 25 '16 at 13:40
  • 5
    Once again, making a [MCVE] that isolates your JSON problem will make it a _lot_ easier for people to help you. That Tkinter and internet stuff makes your question more complicated than it needs to be, and it makes your question _less_ useful for future readers. – PM 2Ring Jan 25 '16 at 13:51
  • 1
    Sorry .. Edited it .. check now/ – TorreZz Jan 25 '16 at 14:23
  • 1
    That's _a lot_ better! – PM 2Ring Jan 25 '16 at 14:42
  • Take a look at [python open built-in function: difference between modes a, a+, w, w+, and r+?](http://stackoverflow.com/a/1466036/4014959) – PM 2Ring Jan 25 '16 at 14:46
  • 1
    Just a tiny comment - I realise this might not be your real code, but don't use `all` as a function name, because there is [a built in function](https://docs.python.org/3/library/functions.html#all) that your name will overshadow if you do. It's a common but hard to debug gotcha in python - you can override built in function names, but you almost never want to. – J Richard Snape Jan 25 '16 at 14:50
  • @JRichardSnape : No thats not my real func name... – TorreZz Jan 25 '16 at 14:58

2 Answers2

3

I suspect you left out that you're getting a TypeError in the blocks where you're trying to write the file. Here's where you're trying to write:

with open('offline_post.json','a') as f:
    new = json.loads(f)
    new.update(a_dict)
    json.dump(new,f)

There's a couple of problems here. First, you're passing a file object to the json.loads command, which expects a string. You probably meant to use json.load.

Second, you're opening the file in append mode, which places the pointer at the end of the file. When you run the json.load, you're not going to get anything because it's reading at the end of the file. You would need to seek to 0 before loading (edit: this would fail anyway, as append mode is not readable).

Third, when you json.dump the new data to the file, it's going to append it to the file in addition to the old data. From the structure, it appears you want to replace the contents of the file (as the new data contains the old data already).

You probably want to use r+ mode, seeking back to the start of the file between the read and write, and truncateing at the end just in case the size of the data structure ever shrinks.

with open('offline_post.json', 'r+') as f:
    new = json.load(f)
    new.update(a_dict)
    f.seek(0)
    json.dump(new, f)
    f.truncate()

Alternatively, you can open the file twice:

with open('offline_post.json', 'r') as f:
    new = json.load(f)
new.update(a_dict)
with open('offline_post.json', 'w') as f:
    json.dump(new, f)
glibdud
  • 7,550
  • 4
  • 27
  • 37
  • I am getting list object has no attribute 'update' error – TorreZz Jan 25 '16 at 15:04
  • @user3041822 Sounds like the JSON is being interpreted as a list. What are the file contents? – glibdud Jan 25 '16 at 15:07
  • [{"body": "uiewf", "title": "jk", "id": "25", "author": "ok"}, {"body": "hbjn", "title": "ghbj", "id": "27", "author": "vghbjn"}] – TorreZz Jan 25 '16 at 15:09
  • @user3041822 That's a list. You can't `update` it. If you're just trying to add another {"body": ... } dict to it, use `append`. – glibdud Jan 25 '16 at 15:11
  • then how can i insert it as JSON file? – TorreZz Jan 25 '16 at 15:13
  • @user3041822 I don't understand the question... just replacing `update` with `append` will probably do what you're expecting it to do. – glibdud Jan 25 '16 at 15:14
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/101600/discussion-between-user3041822-and-glibdud). – TorreZz Jan 25 '16 at 15:15
0

This is a different approach, I just wanted to append without reloading all the data. Running on a raspberry pi so want to look after memory. The test code -

import os

json_file_exists = 0
filename = "/home/pi/scratch_pad/test.json"

# remove the last run json data
try:
    os.remove(filename)
except OSError:
    pass

count = 0
boiler = 90
tower = 78

while count<10:
    if json_file_exists==0:
        # create the json file
        with open(filename, mode = 'w') as fw:  
            json_string = "[\n\t{'boiler':"+str(boiler)+",'tower':"+str(tower)+"}\n]"
            fw.write(json_string)   
            json_file_exists=1
    else:
        # append to the json file
        char = ""
        boiler = boiler + .01
        tower = tower + .02
        while(char<>"}"):
            with open(filename, mode = 'rb+') as f: 
                f.seek(-1,2)
                size=f.tell()
                char = f.read()
                if char == "}":
                    break
                f.truncate(size-1)

        with open(filename, mode = 'a') as fw:  
            json_string = "\n\t,{'boiler':"+str(boiler)+",'tower':"+str(tower)+"}\n]"
            fw.seek(-1, os.SEEK_END)
            fw.write(json_string)

    count = count + 1