-1

I have a rather weird question:

So, I have a simple dictionary in python, looking like so:

data={'Acoustics': {'Product Type': 'Acoustic Pod', 'Width [cm]': '1000', 'Noise Reduction Coefficient': '29 dB', 'Standards, Certification, and Documentation': 'PN EN-ISO 717-1:1999 ;  EN 13501 B, s1, d0', 'Material': 'MDF ;  Glass ;  Acoustic composite', 'Color': 'NCS ;  RAL', 'Installation Method': 'Own assembly ;  Installation by the manufacturer', 'Facing Material': 'MDF ;  Certified Paint', 'Type': 'Adjustable Ventilation ;  Motion Sensor ;  LED 6000K 2W ;  230V ;  RJ45 or USB Charger ;  Integrated seat and shelf'}}

and I try to save this via django onto my pgSQL database (with jsonb column), and I somehow end up with (notice the double quote at the start and end):

"{'Acoustics': {'Product Type': 'Acoustic Pod', 'Width [cm]': '1000', 'Noise Reduction Coefficient': '29 dB', 'Standards, Certification, and Documentation': 'PN EN-ISO 717-1:1999 ;  EN 13501 B, s1, d0', 'Material': 'MDF ;  Glass ;  Acoustic composite', 'Color': 'NCS ;  RAL', 'Installation Method': 'Own assembly ;  Installation by the manufacturer', 'Facing Material': 'MDF ;  Certified Paint', 'Type': 'Adjustable Ventilation ;  Motion Sensor ;  LED 6000K 2W ;  230V ;  RJ45 or USB Charger ;  Integrated seat and shelf'}}"

To add to my DB, I use django forms like so:

form_data={"cvar": data}
form = myform(form_data)
if form.is_valid():
    form.save()

So, now, I have two questions: [1] How do I avoid the above scenario? Why is it getting quoted? I simply pass a form data to save and it somehow ends up as a string rather than json. [2] If I have such quoted json (which unfortunately I do now), how do I unquote and access this as a json (at the moment it is a damn string!).

Thank you.

JohnJ
  • 6,736
  • 13
  • 49
  • 82
  • you should show your example code if you wnat to find the help here. – Brown Bear Nov 12 '18 at 20:35
  • 1
    You are saving the dictionary as a Json string. If you want to transform json string to json object, you can use [`json.loads`](https://docs.python.org/2/library/json.html) – wendelbsilva Nov 12 '18 at 20:36
  • @BearBrown: I have added this now but it is plain vanilla forms.. – JohnJ Nov 12 '18 at 20:47
  • @wendelbsilva: that is definitely not correct. you can try it yourself. – JohnJ Nov 12 '18 at 20:51
  • Please show your model and form definitions. Note, you are confusing things by referring to a string as a different thing than JSON; JSON *is* a string format. However, that string is not actually valid JSON, so something odd is going on. – Daniel Roseman Nov 12 '18 at 20:57
  • Hi @JohnJ. My comment and the answer you select as correct talk about the same concept. Since you mentioned my comment was wrong, Im assuming you cant see their similarity. If that's the case, I would suggest reading about `String`, `Dict`, `Objects` and later, jump to [`json encoder/decoder`](https://docs.python.org/2/library/json.html) to see how you can transform from a `String` representation of JSON to [Python DataStructures](https://docs.python.org/2/library/json.html#json-to-py-table) and vice-versa. – wendelbsilva Nov 13 '18 at 15:06

1 Answers1

1

It isn't easy to figure out without MCVE showing the relevant code.

It looks like you wrote to the database a dictionary converted to string and then converted to JSON, instead of converting the dictionary to json directly.

Like:

>>> import json
>>> a={'Acoustics': {'Product Type': 'Acoustic Pod', 'Width [cm]': '1000', 'Noise Reduction Coefficient': '29 dB', 'Standards, Certification, and Documentation': 'PN EN-ISO 717-1:1999 ;  EN 13501 B, s1, d0', 'Material': 'MDF ;  Glass ;  Acoustic composite', 'Color': 'NCS ;  RAL', 'Installation Method': 'Own assembly ;  Installation by the manufacturer', 'Facing Material': 'MDF ;  Certified Paint', 'Type': 'Adjustable Ventilation ;  Motion Sensor ;  LED 6000K 2W ;  230V ;  RJ45 or USB Charger ;  Integrated seat and shelf'}}

and then:

>>> print(json.dumps(str(a)))
"{'Acoustics': {'Product Type': 'Acoustic Pod', 'Width [cm]': '1000', 'Noise Reduction Coefficient': '29 dB', 'Standards, Certification, and Documentation': 'PN EN-ISO 717-1:1999 ;  EN 13501 B, s1, d0', 'Material': 'MDF ;  Glass ;  Acoustic composite', 'Color': 'NCS ;  RAL', 'Installation Method': 'Own assembly ;  Installation by the manufacturer', 'Facing Material': 'MDF ;  Certified Paint', 'Type': 'Adjustable Ventilation ;  Motion Sensor ;  LED 6000K 2W ;  230V ;  RJ45 or USB Charger ;  Integrated seat and shelf'}}"

instead of:

>>> print(json.dumps(a))
{"Acoustics": {"Product Type": "Acoustic Pod", "Width [cm]": "1000", "Noise Reduction Coefficient": "29 dB", "Standards, Certification, and Documentation": "PN EN-ISO 717-1:1999 ;  EN 13501 B, s1, d0", "Material": "MDF ;  Glass ;  Acoustic composite", "Color": "NCS ;  RAL", "Installation Method": "Own assembly ;  Installation by the manufacturer", "Facing Material": "MDF ;  Certified Paint", "Type": "Adjustable Ventilation ;  Motion Sensor ;  LED 6000K 2W ;  230V ;  RJ45 or USB Charger ;  Integrated seat and shelf"}}

If you already have the python dictionary representation as a string from some external data source, then you can use ast.literal_eval() to turn it to a proper dict first:

>>> the_dict=ast.literal_eval(the_data)
>>> the_json=json.dumps(the_dict)

Or, preferably, change the data source (for example a web form) to use JSON format instead of Python dict text representation for exchanging data.

Tometzky
  • 22,573
  • 5
  • 59
  • 73
  • The problem is that the code base is rather big, and I am extracting parts of it to show relevant info. So, for example, when I have the data dictionary, I do `type(data)` and it outputs `` but, when I do `type(json.dumps(data))` I get `` seems very odd. All I do is pass data to a form, which expects a JSONB field, but when I save the form, I see a string representation of the JSON. – JohnJ Nov 12 '18 at 22:01
  • I have solved it using your answer :) It turns out that the code base had a function which converted everything to a string - very annoying. Anyways, thanks again for all your help. – JohnJ Nov 12 '18 at 22:24