]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
docs: add docs about generic pool 559/head
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>
Wed, 27 Sep 2023 00:38:44 +0000 (02:38 +0200)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Wed, 27 Sep 2023 00:41:00 +0000 (02:41 +0200)
docs/advanced/typing.rst
docs/api/pool.rst

index 71b4e415ce3d5f650f3bb063a2def9ffbd9fea56..5a91f60ea5bc0428ea4fd8fc2ddcc47bac625145 100644 (file)
@@ -64,6 +64,63 @@ cursors and annotate the returned objects accordingly. See
    # drec type is Optional[Dict[str, Any]]
 
 
+.. _pool-generic:
+
+Generic pool types
+------------------
+
+.. versionadded:: 3.2
+
+The `~psycopg_pool.ConnectionPool` class and similar are generic on their
+`!connection_class` argument. The `~psycopg_pool.ConnectionPool.connection()`
+method is annotated as returning a connection of that type, and the record
+returned will follow the rule as in :ref:`row-factory-static`.
+
+Note that, at the moment, if you use a generic class as `!connection_class`,
+you will need to specify a `!row_factory` consistently in the `!kwargs`,
+otherwise the typing system and the runtime will not agree.
+
+.. code:: python
+
+    from psycopg import Connection
+    from psycopg.rows import DictRow, dict_row
+
+    with ConnectionPool(
+        connection_class=Connection[DictRow],   # provides type hinting
+        kwargs={"row_factory": dict_row},       # works at runtime
+    ) as pool:
+        # reveal_type(pool): ConnectionPool[Connection[dict[str, Any]]]
+
+        with pool.connection() as conn:
+            # reveal_type(conn): Connection[dict[str, Any]]
+
+            row = conn.execute("SELECT now()").fetchone()
+            # reveal_type(row): Optional[dict[str, Any]]
+
+            print(row)  # {"now": datetime.datetime(...)}
+
+If a non-generic `!Connection` subclass is used (one whose returned row
+type is not parametric) then it's not necessary to specify `!kwargs`:
+
+.. code:: python
+
+    class MyConnection(Connection[DictRow]):
+        def __init__(self, *args, **kwargs):
+            kwargs["row_factory"] = dict_row
+            super().__init__(*args, **kwargs)
+
+    with ConnectionPool(connection_class=MyConnection[DictRow]) as pool:
+        # reveal_type(pool): ConnectionPool[MyConnection]
+
+        with pool.connection() as conn:
+            # reveal_type(conn): MyConnection
+
+            row = conn.execute("SELECT now()").fetchone()
+            # reveal_type(row): Optional[dict[str, Any]]
+
+            print(row)  # {"now": datetime.datetime(...)}
+
+
 .. _example-pydantic:
 
 Example: returning records as Pydantic models
index aae0719a538ba64a7c87df73169c9f6b234f92dd..5e58537db700be45f7d0148358d28dcf1a690fea 100644 (file)
@@ -154,6 +154,11 @@ The `!ConnectionPool` class
 
         added `!open` parameter to init method.
 
+   .. versionchanged:: 3.2
+
+        The class is generic and `!connection_class` provides types type
+        variable. See :ref:`pool-generic`.
+
    .. note:: In a future version, the default value for the `!open` parameter
         might be changed to `!False`. If you rely on this behaviour (e.g. if
         you don't use the pool as a context manager) you might want to specify
@@ -168,6 +173,10 @@ The `!ConnectionPool` class
 
           # the connection is now back in the pool
 
+      .. versionchanged:: 3.2
+        The connection returned is annotated as defined in `!connection_class`.
+        See :ref:`pool-generic`.
+
    .. automethod:: open
 
       .. versionadded:: 3.1