0

I have a json file

{
    "id_1" : "",
    "id_2": ""
}

I'm trying to update the value for each using the following function

    async def UpdateID(self):
        await self.bot.wait_until_ready()
        while not self.bot.is_closed():
            id1 = 1
            id2 = 2
            with open("file.json", "r+") as r:
                config_json = json.load(r)
                config_json.update({"id_1": "%s" %(id1)})
                config_json.update({"id_2": "%s" %(id2)})
                json.dump(config_json,r)
            await asyncio.sleep(120)

Using mode r+, it copies the file and adds it to the end, thus duplicate all the data instead of replacing. If I use r, I can't write.

If I use w or a, I get an UnsupportedOperation, not readable error on the json.load step. Using w also makes the file empty.

a+ and w+, give a JSONDecodeError,Expecting value: line 1 column 1 (char 0) error on the json.load step.

Am I using the wrong mode, or an improper way of fixing the original problem?

Josh
  • 164
  • 4
  • 16
  • I just tried using `r+` and adding `r.seek(0)` before the dump and `r.truncate()` after. Is that a proper way to go about it? – Josh Oct 14 '20 at 23:14
  • Yes, that's the solution. – Barmar Oct 14 '20 at 23:18
  • 1
    Why use `config_json.update` instead of simply `config_json["id_1"] = str(id1)`? – Barmar Oct 14 '20 at 23:20
  • Bit of a failsafe I guess in case for whatever reason the key doesn't exist, `update` will create it, right? – Josh Oct 14 '20 at 23:23
  • 1
    So does assigning to the dictionary element. – Barmar Oct 14 '20 at 23:25
  • 1
    I think you're confusing it with lists, where you can't create an element with assignment. – Barmar Oct 14 '20 at 23:25
  • Since you figured out the solution yourself, you can post your own answer. – Barmar Oct 14 '20 at 23:26
  • Well, "proper" is stretching it -- `seek(0)` + write + truncate is more prone to leaving your file corrupt or half-written if your program exits abruptly, the system is rebooted at the wrong time, etc. Best practice is to create a new temporary file, write all your content to _that_, and then rename the temporary file over the original when it's fully flushed to disk. See [atomic write to file using Python](https://stackoverflow.com/questions/2333872/atomic-writing-to-file-with-python). – Charles Duffy Oct 15 '20 at 00:39

1 Answers1

0

You can do like this

import json

async def updateId(self):
    do_something()

    with open(file_name) as f:
        config = json.load(f)

    update_your_config()

    with open(file_name, 'w') as f:
         json.dumps(config, f)

    do_something()

ochrv
  • 1
  • 1