]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
Improve AdaptersMap and Copy.set_types() docs
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>
Sun, 26 Sep 2021 20:18:54 +0000 (22:18 +0200)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Sun, 26 Sep 2021 20:29:22 +0000 (22:29 +0200)
docs/api/adapt.rst
docs/basic/copy.rst
psycopg/psycopg/_adapters_map.py
psycopg/psycopg/copy.py

index 3d7b34843e36f6724397a86365a14b0d26dbdeef..36bafa97ea80590411cedfc785008e4acccf8d8a 100644 (file)
@@ -67,6 +67,7 @@ Other objects used in adaptations
        :type: `~psycopg.types.TypesRegistry`
 
    .. automethod:: get_dumper
+   .. automethod:: get_dumper_by_oid
    .. automethod:: get_loader
 
 
index 89af1a6f78bdee089b61edb1e735778e003283d4..2761b3dbf4c97cec235f30fa85655bbd87ddcc6f 100644 (file)
@@ -79,9 +79,8 @@ must have a binary dumper registered (see see :ref:`binary-data`).
 Note that PostgreSQL is particularly finicky when loading data in binary mode
 and will apply *no cast rule*. This means that e.g. passing the value 100 to
 an `integer` column will fail because Psycopg will pass it as a `smallint`
-value. You can work around the problem by registering the right binary
-`~adapt.Dumper` on the cursor (see :ref:`adaptation`) or using the right data
-wrapper (e.g. `~psycopg.types.numeric.Int4`).
+value. You can work around the problem using the `~Copy.set_types()` method of
+the `!Copy` object and specify carefully the types to dump.
 
 
 .. _copy-out-row:
index a2a9681e4b7931594e779b358c23324362e1fe45..4fe93c2822605c74fb6d217817f2725bc0ec6048 100644 (file)
@@ -125,6 +125,12 @@ class AdaptersMap:
         will be possible to register it without importing it before. In this
         case it should be the fully qualified name of the object (e.g.
         ``"uuid.UUID"``).
+
+        If *cls* is None, only use the dumper when looking up using
+        `get_dumper_by_oid()`, which happens when we know the Postgres type to
+        adapt to, but not the Python type that will be adapted (e.g. in COPY
+        after using `~psycopg.Copy.set_types()`).
+
         """
         if not (cls is None or isinstance(cls, (str, type))):
             raise TypeError(
@@ -188,7 +194,11 @@ class AdaptersMap:
         """
         Return the dumper class for the given type and format.
 
-        Raise ProgrammingError if a class is not available.
+        Raise `~psycopg.ProgrammingError` if a class is not available.
+
+        :param cls: The class to adapt.
+        :param format: The format to dump to. If `~psycopg.adapt.PyFormat.AUTO`,
+            use the last one of the dumpers registered on *cls*.
         """
         try:
             dmap = self._dumpers[format]
@@ -216,7 +226,10 @@ class AdaptersMap:
         """
         Return the dumper class for the given oid and format.
 
-        Raise ProgrammingError if a class is not available.
+        Raise `~psycopg.ProgrammingError` if a class is not available.
+
+        :param oid: The oid of the type to dump to.
+        :param format: The format to dump to.
         """
         try:
             dmap = self._dumpers_by_oid[format]
@@ -245,7 +258,10 @@ class AdaptersMap:
         """
         Return the loader class for the given oid and format.
 
-        Return None if not found.
+        Return `!None` if not found.
+
+        :param oid: The oid of the type to load.
+        :param format: The format to load from.
         """
         return self._loaders[format].get(oid)
 
index a237078f5873da68c5a49f76c94cf7c6289764c8..b26041a084a69519d05ef13c277a9d1c9005e76d 100644 (file)
@@ -84,13 +84,22 @@ class BaseCopy(Generic[ConnectionType]):
 
     def set_types(self, types: Sequence[Union[int, str]]) -> None:
         """
-        Set the types expected out of a :sql:`COPY TO` operation.
-
-        Without setting the types, the data from :sql:`COPY TO` will be
-        returned as unparsed strings or bytes.
+        Set the types expected in a COPY operation.
 
         The types must be specified as a sequence of oid or PostgreSQL type
         names (e.g. ``int4``, ``timestamptz[]``).
+
+        This operation overcomes the lack of metadata returned by PostgreSQL
+        when a COPY operation begins:
+
+        - On :sql:`COPY TO`, `!set_types()` allows to specify what types the
+          operation returns. If `!set_types()` is not used, the data will be
+          reurned as unparsed strings or bytes instead of Python objects.
+
+        - On :sql:`COPY FROM`, `!set_types()` allows to choose what type the
+          database expects. This is especially useful in binary copy, because
+          PostgreSQL will apply no cast rule.
+
         """
         registry = self.cursor.adapters.types
         oids = [