]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
Add some docs on TypeInfo and adaptation docs corrections
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>
Mon, 8 Feb 2021 01:42:31 +0000 (02:42 +0100)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Mon, 8 Feb 2021 01:42:31 +0000 (02:42 +0100)
docs/adaptation.rst
docs/api/index.rst
docs/pq.rst
docs/types.rst [new file with mode: 0644]

index 4b951e804d1f8b4795dec3b93e19f0cbcb3e63c7..f5fae47c7229e460092f0144d66b85759ea18067 100644 (file)
@@ -16,21 +16,26 @@ returned.
     described in this page is useful if you intend to *customise* the
     adaptation rules.
 
-The `Dumper` is the base object to perform conversion from a Python object to
-a `!bytes` string understood by PostgreSQL. The string returned *shouldn't be
-quoted*: the value will be passed to the database using functions such as
-:pq:`PQexecParams()` so quoting and quotes escaping is not necessary.
+- The `~psycopg3.types.TypeInfo` object allows to query type information from
+  a database, which can be used by the adapters: for instance to make them
+  able to decode arrays of base types or composite types.
 
-The `Loader` is the base object to perform the opposite operation: to read a
-`!bytes` string from PostgreSQL and create a Python object.
+- The `Dumper` is the base object to perform conversion from a Python object
+  to a `!bytes` string understood by PostgreSQL. The string returned
+  *shouldn't be quoted*: the value will be passed to the database using
+  functions such as :pq:`PQexecParams()` so quoting and quotes escaping is not
+  necessary.
+
+- The `Loader` is the base object to perform the opposite operation: to read a
+  `!bytes` string from PostgreSQL and create a Python object.
 
 `!Dumper` and `!Loader` are abstract classes: concrete classes must implement
 the `~Dumper.dump()` and `~Loader.load()` methods. `!psycopg3` provides
 implementation for several builtin Python and PostgreSQL types.
 
-.. admonition:: TODO
-
-    Document the builtin adapters, where are they?
+Psycopg provides adapters for several builtin types, which can be used as the
+base to build more complex ones: they all live in the `psycopg3.types`
+package.
 
 
 Dumpers and loaders configuration
@@ -74,8 +79,11 @@ right instance.
   `!Connection`, the `!Cursor`.
 
 - For every Python type passed as query argument, the `!Transformer` will
-  instantiate a `!Dumper`. All the objects of the same type will be converted
-  by the same dumper.
+  instantiate a `!Dumper`. Usually all the objects of the same type will be
+  converted by the same dumper; certain dumpers may be used in more than one
+  instance, because the same Python type maps to more than one PostgreSQL type
+  (for instance, a Python `int` might be better dumped as a PostgreSQL
+  :sql:`integer`, :sql:`bigint`, :sql:`smallint` according to its value).
 
 - For every OID returned by the query, the `!Transformer` will instantiate a
   `!Loader`. All the values with the same OID will be converted by the same
index eeae9cc4535d36bc87191c77e9aa26c3548101f4..275906cf71088c39f335cb0963443f69ffad5054 100644 (file)
@@ -9,4 +9,5 @@
     ../cursor
     ../sql
     ../errors
+    ../types
     ../pq
index 1f8788059e51430b5a0f2828f30014c5a50d7d0c..cfc95e9cbd35477f82496fcd8e5c2c80fccec3e9 100644 (file)
@@ -1,6 +1,6 @@
 .. _psycopg3.pq:
 
-`pq` -- Libpq wrapper module
+`pq` -- libpq wrapper module
 ============================
 
 .. index::
diff --git a/docs/types.rst b/docs/types.rst
new file mode 100644 (file)
index 0000000..3f144bb
--- /dev/null
@@ -0,0 +1,107 @@
+.. currentmodule:: psycopg3.types
+
+.. _psycopg3.types:
+
+`!types` -- types mapping and adaptation
+========================================
+
+.. module:: psycopg3.types
+
+The `!psycopg3.types` package exposes the concrete implementation of `Loader`
+and `Dumper` to manage builtin objects, together with objects to describe
+PostgreSQL types and wrappers to help or customise the types conversion.
+
+
+Types information
+-----------------
+
+The `TypeInfo` object describes simple information about a PostgreSQL data
+type, such as its name, oid and array oid. The class can be used to query a
+database for custom data types: this allows for instance to load automatically
+arrays of a custom type, once a loader for the base type has been registered.
+
+The `!TypeInfo` object doesn't instruct `!psycopg3` to convert a PostgreSQL
+type into a Python type: this is the role of a `Loader`. However it can extend
+the behaviour of the adapters: if you create a loader for `!MyType`, using
+`TypeInfo` you will be able to manage seamlessly arrays of `!MyType` or ranges
+and composite types using it as a subtypes.
+
+.. seealso:: :ref:`adaptation` describes about how to convert from Python
+    types to PostgreSQL types and back.
+
+.. code:: python
+
+    from psycopg3.adapt import Loader
+    from psycopg3.types import TypeInfo
+
+    t = TypeInfo.fetch(conn, "mytype")
+    t.register(conn)
+
+    for record in conn.execute("select mytypearray from mytable"):
+        # records will return lists of "mytype" as string
+
+    class MyTypeLoader(Loader):
+        def load(self, data):
+            # parse the data and return a MyType instance
+
+    MyTypeLoader.register(conn)
+
+    for record in conn.execute("select mytypearray from mytable"):
+        # records will return lists of MyType instances
+
+
+.. autoclass:: TypeInfo
+
+    .. automethod:: fetch
+    .. automethod:: fetch_async
+    .. automethod:: register
+
+        The *context* can be a `~psycopg3.Connection` or `~psycopg3.Cursor`.
+        Specifying no context will register the `!TypeInfo` globally.
+
+        Registering the `TypeInfo` in a context allows the adapters of that
+        context to look up type information: for instance it allows to
+        recognise automatically arrays of that type and load them from the
+        database as a list of the base type (how the base type is converted to
+        Python is demanded to a `Loader`.
+
+
+The following `!TypeInfo` subclasses allow to fetch more specialised
+information from certain class of PostgreSQL types and to create more
+specialised adapters configurations.
+
+
+.. autoclass:: CompositeInfo
+
+    .. automethod:: register
+
+        Using `!CompositeInfo.register()` will also register a specialised
+        loader to fetch the composite type as a Python named tuple, or a
+        custom object if *factory* is specified.
+
+
+.. autoclass:: RangeInfo
+
+    .. automethod:: register
+
+        Using `!RangeInfo.register()` will also register a specialised loaders
+        and dumpers. For instance, if you create a PostgreSQL range on the
+        type :sql:`inet`, loading these object with the database will use the
+        loader for the :sql:`inet` type to parse the range bounds - either the
+        builtin ones or any one you might have configured.
+
+        The type information will also be used by the `Range` dumper so that
+        if you dump a `!Range(address1, address2)` object it will use the
+        correct oid for your :sql:`inetrange` type.
+
+
+Objects wrappers
+----------------
+
+.. admonition:: TODO
+
+    Document the various objects wrappers
+
+    - Int2, Int4, Int8, ...
+    - Json, Jsonb
+    - Range