From: Daniele Varrazzo Date: Tue, 27 Oct 2020 18:47:05 +0000 (+0100) Subject: Added JSON loaders X-Git-Tag: 3.0.dev0~442^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2b1ae82085c4fdda62bf6d8f6b1b6350f746610a;p=thirdparty%2Fpsycopg.git Added JSON loaders --- diff --git a/psycopg3/psycopg3/types/json.py b/psycopg3/psycopg3/types/json.py index eb81ef2bb..4134035fb 100644 --- a/psycopg3/psycopg3/types/json.py +++ b/psycopg3/psycopg3/types/json.py @@ -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:]) diff --git a/tests/types/test_json.py b/tests/types/test_json.py index 9c003cd58..95eb1de2b 100644 --- a/tests/types/test_json.py +++ b/tests/types/test_json.py @@ -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)