Skip to content

Commit d2e89ba

Browse files
fix: handle psycopg2 auto-deserialized JSON in codecs
psycopg2 automatically deserializes JSONB columns to Python dict/list, unlike PyMySQL which returns strings. Check if data is already deserialized before calling json.loads(). Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent fd4e011 commit d2e89ba

File tree

1 file changed

+7
-2
lines changed

1 file changed

+7
-2
lines changed

src/datajoint/codecs.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,9 @@ def decode_attribute(attr, data, squeeze: bool = False):
544544

545545
# Process the final storage type (what's in the database)
546546
if final_dtype.lower() == "json":
547-
data = json.loads(data)
547+
# psycopg2 auto-deserializes JSON to dict/list; only parse strings
548+
if isinstance(data, str):
549+
data = json.loads(data)
548550
elif final_dtype.lower() in ("longblob", "blob", "mediumblob", "tinyblob"):
549551
pass # Blob data is already bytes
550552
elif final_dtype.lower() == "binary(16)":
@@ -562,7 +564,10 @@ def decode_attribute(attr, data, squeeze: bool = False):
562564

563565
# No codec - handle native types
564566
if attr.json:
565-
return json.loads(data)
567+
# psycopg2 auto-deserializes JSON to dict/list; only parse strings
568+
if isinstance(data, str):
569+
return json.loads(data)
570+
return data
566571

567572
if attr.uuid:
568573
import uuid as uuid_module

0 commit comments

Comments
 (0)