From: Daniele Varrazzo Date: Sat, 28 Aug 2021 03:51:16 +0000 (+0200) Subject: Add documentation for range types X-Git-Tag: 3.0.beta1~23 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=0a313bad0c5b8f8ad0d420be79e932beafb7a463;p=thirdparty%2Fpsycopg.git Add documentation for range types --- diff --git a/docs/api/types.rst b/docs/api/types.rst index 94c734743..6414e71c8 100644 --- a/docs/api/types.rst +++ b/docs/api/types.rst @@ -88,13 +88,9 @@ can extend the behaviour of the adapters: if you create a loader for database as a list of the base type. -The following `!TypeInfo` subclasses allow to fetch more specialised -information from certain class of PostgreSQL types. - -.. autoclass:: psycopg.types.composite.CompositeInfo - -.. autoclass:: psycopg.types.range.RangeInfo - +For recursive types, Psycopg offers a few `!TypeInfo` subclasses which can be +used to extract more complete information, for instance +`~psycopg.types.composite.CompositeInfo` and `~psycopg.types.range.RangeInfo`. `!TypeInfo` objects are collected in `TypesRegistry` instances, which help type information lookup. Every `~psycopg.adapt.AdaptersMap` expose its type map on diff --git a/docs/basic/adapt.rst b/docs/basic/adapt.rst index 9dcc9ff16..26c55512c 100644 --- a/docs/basic/adapt.rst +++ b/docs/basic/adapt.rst @@ -7,8 +7,8 @@ .. _types-adaptation: -Adaptation between Python and PostgreSQL types -============================================== +Adapting basic Python types +=========================== Many standard Python types are adapted into SQL and returned as Python objects when a query is executed. @@ -32,8 +32,6 @@ TODO: complete table +--------------------+-------------------------+--------------------------+ | `!dict` | :sql:`hstore` | :ref:`adapt-hstore` | +--------------------+-------------------------+--------------------------+ - | Psycopg's `!Range` | :sql:`range` | :ref:`adapt-range` | - +--------------------+-------------------------+--------------------------+ .. index:: @@ -377,7 +375,6 @@ address types`__: .. _adapt-composite: .. _adapt-hstore: -.. _adapt-range: TODO adaptation diff --git a/docs/basic/index.rst b/docs/basic/index.rst index 33f78ff9a..d7c559186 100644 --- a/docs/basic/index.rst +++ b/docs/basic/index.rst @@ -15,6 +15,7 @@ the database ` or :ref:`loading data using COPY `. usage params adapt + pgtypes transactions copy from_pg2 diff --git a/docs/basic/pgtypes.rst b/docs/basic/pgtypes.rst new file mode 100644 index 000000000..7c4bd034d --- /dev/null +++ b/docs/basic/pgtypes.rst @@ -0,0 +1,83 @@ +.. currentmodule:: psycopg + +.. index:: + single: Adaptation + pair: Objects; Adaptation + single: Data types; Adaptation + +.. _extra-adaptation: + +Adapting other PostgreSQL types +=============================== + +PostgreSQL offers other data types which don't map to native Python types. +Psycopg offers wrappers and conversion functions to allow their use. + + +.. _adapt-range: + +Range adaptation +---------------- + +PostgreSQL `range types`__ are a family of data types representing a range of +value between two elements. The type of the element is called the range +*subtype*. PostgreSQL offers a few built-in range types and allows the +definition of custom ones. + +.. __: https://www.postgresql.org/docs/current/rangetypes.html + +All the PostgreSQL range types are loaded as the `~psycopg.types.range.Range` +Python type, which is a `~typing.Generic` type and can hold bounds of +different types. + +.. autoclass:: psycopg.types.range.Range + + This Python type is only used to pass and retrieve range values to and + from PostgreSQL and doesn't attempt to replicate the PostgreSQL range + features: it doesn't perform normalization and doesn't implement all the + operators__ supported by the database. + + .. __: https://www.postgresql.org/docs/current/static/functions-range.html#RANGE-OPERATORS-TABLE + + `!Range` objects are immutable, hashable, and support the ``in`` operator + (checking if an element is within the range). They can be tested for + equivalence. Empty ranges evaluate to `!False` in boolean context, + nonempty evaluate to `!True`. + + `!Range` objects have the following attributes: + + .. autoattribute:: isempty + .. autoattribute:: lower + .. autoattribute:: upper + .. autoattribute:: lower_inc + .. autoattribute:: upper_inc + .. autoattribute:: lower_inf + .. autoattribute:: upper_inf + +The built-in range objects are adapted automatically: if a `!Range` objects +contains `~datetime.date` bounds, it is dumped using the :sql:`daterange` OID, +and of course :sql:`daterange` values are loaded back as `!Range[date]`. + +If you create your own range type you can use `~psycopg.types.range.RangeInfo` +and `~psycopg.types.range.register_range()` to associate the range type with +its subtype and make it work like the builtin ones. + +.. autoclass:: psycopg.types.range.RangeInfo + + `~RangeInfo` is a `~psycopg.types.TypeInfo` subclass: check its + documentation for generic details. + +.. autofunction:: psycopg.types.range.register_range + +Example:: + + >>> conn.execute("create type strrange as range (subtype = text)") + + >>> info = RangeInfo.fetch(conn, "strrange") + >>> register_range(info, conn) + + >>> conn.execute("select pg_typeof(%s)", [Range("a", "z")]).fetchone()[0] + 'strrange' + + >>> conn.execute("select '[a,z]'::strrange").fetchone()[0] + Range('a', 'z', '[]') diff --git a/psycopg/psycopg/types/range.py b/psycopg/psycopg/types/range.py index 5c1652759..a9f32cdc2 100644 --- a/psycopg/psycopg/types/range.py +++ b/psycopg/psycopg/types/range.py @@ -31,7 +31,7 @@ T = TypeVar("T") class Range(Generic[T]): - """Python representation for a PostgreSQL |range|_ type. + """Python representation for a PostgreSQL range type. :param lower: lower bound for the range. `!None` means unbound :param upper: upper bound for the range. `!None` means unbound @@ -441,9 +441,8 @@ def register_range( """ Register custom range adapters on a context. - Just register loaders associated to the range oid, loading bounds of the - right subtype. Dumping the range just works, navigating from tye Python - type to the type oid, to the range oid. + Register loaders so that loading data of this type will result in a `Range` + with bounds parsed as the right subtype. """ # Register arrays and type info