Hi, hope everyone is well.
Just nearing the basics end of PCC book, I'm at saving user's data now. What exactly is the reason, when storing simple data, to use json.dump() or load(), instead of just saving and then reading it from simple text file?
I just can't place it in my head why do I really need it and it always makes it more difficult for me to learn if that's the case.
Thank you all in advance.
Videos
If you want to dump the JSON into a file/socket or whatever, then you should go with dump(). If you only need it as a string (for printing, parsing or whatever) then use dumps() (dump string)
As mentioned by Antti Haapala in this answer, there are some minor differences on the ensure_ascii behaviour. This is mostly due to how the underlying write() function works, being that it operates on chunks rather than the whole string. Check his answer for more details on that.
json.dump()
Serialize obj as a JSON formatted stream to fp (a .write()-supporting file-like object
If ensure_ascii is False, some chunks written to fp may be unicode instances
json.dumps()
Serialize obj to a JSON formatted str
If ensure_ascii is False, the result may contain non-ASCII characters and the return value may be a unicode instance
In memory usage and speed.
When you call jsonstr = json.dumps(mydata) it first creates a full copy of your data in memory and only then you file.write(jsonstr) it to disk. So this is a faster method but can be a problem if you have a big piece of data to save.
When you call json.dump(mydata, file) -- without 's', new memory is not used, as the data is dumped by chunks. But the whole process is about 2 times slower.
Source: I checked the source code of json.dump() and json.dumps() and also tested both the variants measuring the time with time.time() and watching the memory usage in htop.
When you do json.dump you can pass data into the function and where to put it, and it creates a new json file. How could I do this but have the language be python when it dumps? I need to do this because json does not read tuples and other things I am wanting to save into the file. Thanks
Hi all,
I have another assignment where I've been asked to write a Python code to dump the JSON data from an API into a database table. The instructors all say to use dumps, however, I keep getting an error about string formatting. I know I am missing something simple.
Here is the assignment:
| Load the first 100 Pokemon JSON documents from the PokeAPI and store them in a table: |
|---|
| CREATE TABLE IF NOT EXISTS pokeapi (id INTEGER, body JSONB); |
| You need to write this code from scratch. All you need to do is loop through and retrieve the JSON data for urls ending in 1..100 and store it in the above table. |
That is literally all that the actual assignment provides. The instructor put this pseudocode in the discussion forums because a lot of people were frustrated by the lack of clarity in the assignment.
1 range() loop 2 concatenate count to the url 3 requests.get() 4 json() 5 dumps() 6 sql = INSERT... 7 cur.execute() 8 9 conn.commit() 10 cur.close()
This is what I have come up with so far:
1 import psycopg2 2 import hidden 3 import time 4 import myutils 5 import requests 6 import json 7 8 secrets = hidden.secrets() 9 10 conn = psycopg2.connect(host=secrets['host'], 11 port=secrets['port'], 12 database=secrets['database'], 13 user=secrets['user'], 14 password=secrets['pass'], 15 connect_timeout=5) 16 17 cur = conn.cursor() 18 19 sql = 'DROP TABLE IF EXISTS pokeapi CASCADE;' 20 print(sql) 21 cur.execute(sql) 22 23 sql = 'CREATE TABLE IF NOT EXISTS pokeapi (id INTEGER, body JSONB);' 24 print(sql) 25 cur.execute(sql) 26 27 conn.commit() 28 29 defaulturl = 'https://pokeapi.co/api/v2/pokemon-species/' 30 31 for i in range(1, 100): 32 url = 'https://pokeapi.co/api/v2/pokemon-species/' + str(i) 33 print(url) 34 r = requests.get(url) 35 j = r.json() 36 w = json.dumps(j) 37 sql = 'INSERT INTO pokeapi (id, body) VALUES (%s, w);' 38 cur.execute(sql, (i, json)) 39 40 conn.commit() 41 cur.close()
When I run it like that I get this error:
DROP TABLE IF EXISTS pokeapi CASCADE;
CREATE TABLE IF NOT EXISTS pokeapi (id INTEGER, body JSONB);
https://pokeapi.co/api/v2/pokemon-species/1
Traceback (most recent call last):
File "/home/[myname]/pokeapi.py", line 38, in <module>
cur.execute(sql, (i, json))
TypeError: not all arguments converted during string formattingI even put a print(w) line between 36 and 37 and it did a whole bunch of JSON so the problem, I'm guessing, is with the INSERT statement or the execution.
I have tried everything that I can think of in the execute statement (i, w), (i, text), (i, json), (int, text), (int, json) and so many other variations.
I am sure that I am missing something obvious to a veteran programmer. This class is literally my first exposure to computer programming and I feel like I've done okay except for the last two assignments.
I appreciate all of your help!
Thank you :)
Hi! I'm running a Python Back-End with an Android client in Java. I'm trying to return a JSON response to a request that I'm receiving. I've had previous issues with this, as my request has objects within objects but that was solved using a custom Encoder. Now, when I return my response after using json.dumps(), my Java client, parses it through GSON but it's invalid
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 2 path $
When printing the response out in the console I get:
{"user": {"firstName": "Bob", "lastName": "Miller", "username": "bobbyboi", "profileImage": "image"}, "authToken": {"authToken": "authtoken", "dateTime": "time"}} which looks correct, but not for GSON. It ends up coming in as
"{"user": {"firstName": "Bob", "lastName": "Miller", "username": "bobbyboi", "profileImage": "image"}, "authToken": {"authToken": "authtoken", "dateTime": "time"}}" with the extra apostrophes at the end.
Here is my python code:
dummyUser = User("Bob", "Miller", "bobbyboi", "image")
dummyAuth = AuthToken("authtoken", "time")
response = LoginResponse(dummyUser, dummyAuth)
return json.dumps(response, cls=MyEncoder) And the encoder, just in case that's the issue:
class MyEncoder(json.JSONEncoder):
def default(self, o):
if hasattr(o, "encode"):
return o.encode()
else:
return json.JSONEncoder.default(self,o) And then the Java GSON:
if (http.getResponseCode() == HttpURLConnection.HTTP_OK){
InputStream inputStream = http.getInputStream();
String parseRequest = readString(inputStream); System.out.println(parseRequest);LoginResponse response = gson.fromJson(parseRequest, LoginResponse.class)
EDIT: Thanks, guys, for responding! I ended up fixing it by just modifying the string on the Java side to remove the extra paratheses and the backslashes "/" which apparently GSON doesn't like? I've used GSON before with Java backends and never had this issue before. Weird....Thanks for your help though!