]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
Added JSON loaders
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>
Tue, 27 Oct 2020 18:47:05 +0000 (19:47 +0100)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Wed, 28 Oct 2020 03:17:28 +0000 (04:17 +0100)
psycopg3/psycopg3/types/json.py
tests/types/test_json.py

index eb81ef2bb41ce296ac75b04907668e54170ee762..4134035fbaa61d924424682b8e3c9405c0176bba 100644 (file)
@@ -9,8 +9,9 @@ import codecs
 from typing import Any, Callable, Optional
 
 from .oids import builtins
-from ..adapt import Dumper
+from ..adapt import Dumper, Loader
 from ..proto import EncodeFunc
+from ..errors import DataError
 
 _encode_utf8 = codecs.lookup("utf8").encode
 
@@ -67,3 +68,19 @@ class BinaryJsonBDumper(JsonBDumper):
         self, obj: _JsonWrapper, __encode: EncodeFunc = _encode_utf8
     ) -> bytes:
         return b"\x01" + __encode(obj.dumps())[0]
+
+
+@Loader.text(builtins["json"].oid)
+@Loader.text(builtins["jsonb"].oid)
+@Loader.binary(builtins["json"].oid)
+class JsonLoader(Loader):
+    def load(self, data: bytes) -> Any:
+        return json.loads(data)
+
+
+@Loader.binary(builtins["jsonb"].oid)
+class BinaryJsonBLoader(Loader):
+    def load(self, data: bytes) -> Any:
+        if data and data[0] != 1:
+            raise DataError("unknown jsonb binary format: {data[0]}")
+        return json.loads(data[1:])
index 9c003cd58b78bb1cc0e01afd944866a394cef740..95eb1de2b275045362a0ed04448d379ffa3b2ab1 100644 (file)
@@ -40,9 +40,13 @@ def test_jsonb_dump(conn, val, fmt_in):
     assert cur.fetchone()[0] is True
 
 
-def my_dumps(obj):
-    obj["baz"] = "qux"
-    return json.dumps(obj)
+@pytest.mark.parametrize("val", samples)
+@pytest.mark.parametrize("jtype", ["json", "jsonb"])
+@pytest.mark.parametrize("fmt_out", [Format.TEXT, Format.BINARY])
+def test_json_load(conn, val, jtype, fmt_out):
+    cur = conn.cursor(format=fmt_out)
+    cur.execute(f"select %s::{jtype}", (val,))
+    assert cur.fetchone()[0] == json.loads(val)
 
 
 @pytest.mark.parametrize("fmt_in", [Format.TEXT, Format.BINARY])
@@ -72,3 +76,8 @@ def test_json_dump_subclass(conn, wrapper, fmt_in):
     cur = conn.cursor()
     cur.execute(f"select {ph}->>'baz' = 'qux'", (MyWrapper(obj),))
     assert cur.fetchone()[0] is True
+
+
+def my_dumps(obj):
+    obj["baz"] = "qux"
+    return json.dumps(obj)