.. code:: python
- from psycopg3.types import Jsonb
+ from psycopg3.types.json import Jsonb
thing = {"foo": ["bar", 42]}
conn.execute("insert into mytable values (%s)", [Jsonb(thing)])
`json.loads()`__ functions to serialize and de-serialize Python objects to
JSON. If you want to customise globally how serialization happens, for
instance changing serialization parameters or using a different JSON library,
-you can specify your own functions using the `psycopg3.types.set_json_dumps()`
-and `~psycopg3.types.set_json_loads()` functions.
+you can specify your own functions using the
+`psycopg3.types.json.set_json_dumps()` and
+`~psycopg3.types.json.set_json_loads()` functions.
..
weird: intersphinx doesn't work
.. code:: python
from functools import partial
- from psycopg3.types import Jsonb, set_json_dumps, set_json_loads
+ from psycopg3.types.json import Jsonb, set_json_dumps, set_json_loads
import ujson
# Use a faster dump function
# Copyright (C) 2020-2021 The Psycopg Team
-from ..oids import INVALID_OID
-from ..proto import AdaptContext
-from .array import register_all_arrays
-from . import range as _range
+from typing import TYPE_CHECKING
-# Wrapper objects
-from ..wrappers.numeric import (
- Int2 as Int2,
- Int4 as Int4,
- Int8 as Int8,
- IntNumeric as IntNumeric,
- Oid as Oid,
-)
-from .json import Json as Json, Jsonb as Jsonb
-from .range import Range as Range
+from . import json as _json
+from . import array as _array
+from . import range as _range
+from . import numeric as _numeric
# Database types descriptors
-from .._typeinfo import (
- TypeInfo as TypeInfo,
- RangeInfo as RangeInfo,
- CompositeInfo as CompositeInfo,
-)
-
-# Json global registrations
-from .json import (
- set_json_dumps as set_json_dumps,
- set_json_loads as set_json_loads,
-)
+from .._typeinfo import TypeInfo as TypeInfo # exported here
# Adapter objects
from .text import (
CompositeBinaryLoader as CompositeBinaryLoader,
)
+if TYPE_CHECKING:
+ from ..proto import AdaptContext
+
+
+def register_default_globals(ctx: "AdaptContext") -> None:
+
+ from ..oids import INVALID_OID
-def register_default_globals(ctx: AdaptContext) -> None:
# NOTE: the order the dumpers are registered is relevant.
# The last one registered becomes the default for each type.
# Normally, binary is the default dumper, except for text (which plays
# (see tests/scripts/testdec.py for a rough benchmark)
DecimalBinaryDumper.register("decimal.Decimal", ctx)
DecimalDumper.register("decimal.Decimal", ctx)
- Int2Dumper.register(Int2, ctx)
- Int4Dumper.register(Int4, ctx)
- Int8Dumper.register(Int8, ctx)
- IntNumericDumper.register(IntNumeric, ctx)
- OidDumper.register(Oid, ctx)
- Int2BinaryDumper.register(Int2, ctx)
- Int4BinaryDumper.register(Int4, ctx)
- Int8BinaryDumper.register(Int8, ctx)
- OidBinaryDumper.register(Oid, ctx)
+ Int2Dumper.register(_numeric.Int2, ctx)
+ Int4Dumper.register(_numeric.Int4, ctx)
+ Int8Dumper.register(_numeric.Int8, ctx)
+ IntNumericDumper.register(_numeric.IntNumeric, ctx)
+ OidDumper.register(_numeric.Oid, ctx)
+ Int2BinaryDumper.register(_numeric.Int2, ctx)
+ Int4BinaryDumper.register(_numeric.Int4, ctx)
+ Int8BinaryDumper.register(_numeric.Int8, ctx)
+ OidBinaryDumper.register(_numeric.Oid, ctx)
IntLoader.register("int2", ctx)
IntLoader.register("int4", ctx)
IntLoader.register("int8", ctx)
# Currently json binary format is nothing different than text, maybe with
# an extra memcopy we can avoid.
- JsonBinaryDumper.register(Json, ctx)
- JsonDumper.register(Json, ctx)
- JsonbBinaryDumper.register(Jsonb, ctx)
- JsonbDumper.register(Jsonb, ctx)
+ JsonBinaryDumper.register(_json.Json, ctx)
+ JsonDumper.register(_json.Json, ctx)
+ JsonbBinaryDumper.register(_json.Jsonb, ctx)
+ JsonbDumper.register(_json.Jsonb, ctx)
JsonLoader.register("json", ctx)
JsonbLoader.register("jsonb", ctx)
JsonBinaryLoader.register("json", ctx)
CidrLoader.register("cidr", ctx)
CidrBinaryLoader.register("cidr", ctx)
- RangeBinaryDumper.register(Range, ctx)
- RangeDumper.register(Range, ctx)
+ RangeBinaryDumper.register(_range.Range, ctx)
+ RangeDumper.register(_range.Range, ctx)
Int4RangeDumper.register(_range.Int4Range, ctx)
Int8RangeDumper.register(_range.Int8Range, ctx)
NumericRangeDumper.register(_range.NumericRange, ctx)
RecordLoader.register("record", ctx)
RecordBinaryLoader.register("record", ctx)
- register_all_arrays(ctx)
+ _array.register_all_arrays(ctx)
from ..adapt import Format, RecursiveDumper, RecursiveLoader
from ..proto import AdaptContext, Buffer
from .._struct import unpack_len
-from .._typeinfo import CompositeInfo
+from .._typeinfo import CompositeInfo as CompositeInfo # exported here
_struct_oidlen = struct.Struct("!Ii")
_unpack_oidlen = cast(
from .._struct import pack_int4, pack_uint4, unpack_int4, unpack_uint4
from .._struct import pack_int8, unpack_int8
from .._struct import pack_float8, unpack_float4, unpack_float8
-from ..wrappers.numeric import Int2, Int4, Int8, IntNumeric
# Wrappers to force numbers to be cast as specific PostgreSQL types
+class Int2(int):
+ def __new__(cls, arg: int) -> "Int2":
+ return super().__new__(cls, arg)
+
+
+class Int4(int):
+ def __new__(cls, arg: int) -> "Int4":
+ return super().__new__(cls, arg)
+
+
+class Int8(int):
+ def __new__(cls, arg: int) -> "Int8":
+ return super().__new__(cls, arg)
+
+
+class IntNumeric(int):
+ def __new__(cls, arg: int) -> "IntNumeric":
+ return super().__new__(cls, arg)
+
+
+class Oid(int):
+ def __new__(cls, arg: int) -> "Oid":
+ return super().__new__(cls, arg)
+
+
class NumberDumper(Dumper):
format = Format.TEXT
from ..adapt import Format as Pg3Format
from ..proto import AdaptContext, Buffer
from .._struct import pack_len, unpack_len
-from .._typeinfo import RangeInfo
+from .._typeinfo import RangeInfo as RangeInfo # exported here
from .composite import SequenceDumper, BaseCompositeLoader
+++ /dev/null
-"""
-Wrappers to force numbers to be cast as specific PostgreSQL types
-"""
-
-# Copyright (C) 2020-2021 The Psycopg Team
-
-
-class Int2(int):
- def __new__(cls, arg: int) -> "Int2":
- return super().__new__(cls, arg)
-
-
-class Int4(int):
- def __new__(cls, arg: int) -> "Int4":
- return super().__new__(cls, arg)
-
-
-class Int8(int):
- def __new__(cls, arg: int) -> "Int8":
- return super().__new__(cls, arg)
-
-
-class IntNumeric(int):
- def __new__(cls, arg: int) -> "IntNumeric":
- return super().__new__(cls, arg)
-
-
-class Oid(int):
- def __new__(cls, arg: int) -> "Oid":
- return super().__new__(cls, arg)
from psycopg3_c._psycopg3 cimport endian
from psycopg3 import errors as e
-from psycopg3.wrappers.numeric import Int2, Int4, Int8, IntNumeric
+from psycopg3.types.numeric import Int2, Int4, Int8, IntNumeric
cdef extern from "Python.h":
# work around https://github.com/cython/cython/issues/3909
from psycopg3 import sql
from psycopg3.adapt import Format
from psycopg3.types.range import Range
-from psycopg3.wrappers.numeric import Int4, Int8
+from psycopg3.types.numeric import Int4, Int8
@pytest.fixture
from psycopg3 import errors as e
from psycopg3.pq import Format
from psycopg3.adapt import Format as PgFormat
-from psycopg3.types import Int4
+from psycopg3.types.numeric import Int4
from .utils import gc_collect
from psycopg3.sql import Identifier
from psycopg3.oids import postgres_types as builtins
from psycopg3.adapt import Format, global_adapters
-from psycopg3.types import CompositeInfo
+from psycopg3.types.composite import CompositeInfo
tests_str = [
import psycopg3.types
from psycopg3 import pq
from psycopg3 import sql
-from psycopg3.types import Json, Jsonb
from psycopg3.adapt import Format
-from psycopg3.types import set_json_dumps, set_json_loads
+from psycopg3.types.json import Json, Jsonb, set_json_dumps, set_json_loads
samples = [
"null",
@pytest.mark.parametrize("fmt_in", [Format.AUTO, Format.TEXT, Format.BINARY])
@pytest.mark.parametrize("wrapper", ["Json", "Jsonb"])
def test_json_dump_customise(conn, wrapper, fmt_in):
- wrapper = getattr(psycopg3.types, wrapper)
+ wrapper = getattr(psycopg3.types.json, wrapper)
obj = {"foo": "bar"}
cur = conn.cursor()
@pytest.mark.parametrize("wrapper", ["Json", "Jsonb"])
def test_json_dump_subclass(conn, wrapper, fmt_in):
JDumper = getattr(
- psycopg3.types,
+ psycopg3.types.json,
f"{wrapper}{'Binary' if fmt_in != Format.TEXT else ''}Dumper",
)
- wrapper = getattr(psycopg3.types, wrapper)
+ wrapper = getattr(psycopg3.types.json, wrapper)
class MyJsonDumper(JDumper):
def get_dumps(self):
@pytest.mark.parametrize("pgtype", ["json", "jsonb"])
def test_json_load_subclass(conn, binary, pgtype):
JLoader = getattr(
- psycopg3.types,
+ psycopg3.types.json,
f"{pgtype.title()}{'Binary' if binary else ''}Loader",
)
from psycopg3 import pq
from psycopg3.sql import Identifier
from psycopg3.adapt import Format
-from psycopg3.types import Range, RangeInfo
+from psycopg3.types.range import Range, RangeInfo
type2sub = {