#32981 closed Bug (duplicate)
raw sql with postgres jsonb_array_elements no longer deserialises in Django 3.2.5.
| Reported by: | Tim Richardson | Owned by: | nobody |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | 3.2 |
| Severity: | Normal | Keywords: | |
| Cc: | Triage Stage: | Unreviewed | |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
A query that returned a dicts in the fetchall() result now returns a string which is json. In django 3.2.5, it is no longer deserialised to a dict.
This is a very big change in behaviour. Did I miss something? I must have, somewhere. I will keep looking. This was a nasty surprise :)
Seen on postgres 12, django 3.2.5 and both psycopg2-binary==2.8.6 \= and latest sycopg2-binary
The database table has a jsonb field.
Here is a simplified value for the field jdata
{
"Fulfilments":[
"Pick":{
"Lines":[
{
"SKU":"sku1",
"Name":"furniture1",
},
{
"SKU":"sku2",
"Name":"furniture2",
},
]
},
]
}
Example:
from django.db import connection
def test_raw_sql():
dear_api = setup_dear(dear_entity=os.getenv("DEAR_ENTITY"))
dear_cached_api = DearCachedAPI(dear_api=dear_api)
sql = """
select jdata,
jsonb_array_elements(cached_dear_dearcache.jdata#>'{Fulfilments}')->'Pick' as picks
from cached_dear_dearcache
"""
with connection.cursor() as cursor:
cursor.execute(sql)
rows = cursor.fetchall()
return rows
both the first and the second element of the results tuple should be a dict.
In Django 2.2.x, this is what happens.
For example, the second element is a dict:
pick_lines = row[1]
then
pick_lines is {'Lines':[{"SKU": "sku1" ....
In Django 3.2.5 both elements per row are now str. It is a json string, not deserialised into a dict. It is definitely json, as it uses null for None for instance.
This is a big problem, as iterators expecting a dict no longer work, obviously.
for e.g.
for line in pick_lines['Lines']:
....
now breaks when pick_lines is a (json) str.
Although to be honest, the easiest way to see this is that even the first element, jsonb, is not deserialised.
This problem is reproducible simply by swapping to django==3.2.*
It works for every version of 2.2.*
This is based on production code running on postgresql from v 9.6 to v 12.
I have reproduced the 3.2.5 behaviour in postgresql v10 and v12.
Change History (2)
comment:1 by , 4 years ago
| Component: | Uncategorized → Database layer (models, ORM) |
|---|---|
| Resolution: | → duplicate |
| Status: | new → closed |
| Type: | Uncategorized → Bug |
comment:2 by , 4 years ago
| Summary: | raw sql with postgres jsonb_array_elements no longer deserialises in Django 3.2.5, worked in 2.2.* → raw sql with postgres jsonb_array_elements no longer deserialises in Django 3.2.5. |
|---|
Duplicate of #31991, see comment and 3.1.1 release notes.