The `!Connection` class
-----------------------
-.. autoclass:: Connection
+.. autoclass:: Connection()
This class implements a `DBAPI-compliant interface`__. It is what you want
to use if you write a "classic", blocking program (eventually using
:annotation: bool
The property is writable for sync connections, read-only for async
- ones: you should call `!await` `~AsyncConnection.set_autocommit`\
+ ones: you should call ``await`` `~AsyncConnection.set_autocommit`\
:samp:`({value})` instead.
.. rubric:: Checking and configuring the connection state
:annotation: str
The property is writable for sync connections, read-only for async
- ones: you should call `!await` `~AsyncConnection.set_client_encoding`\
+ ones: you should call ``await`` `~AsyncConnection.set_client_encoding`\
:samp:`({value})` instead.
.. attribute:: info
The `!AsyncConnection` class
----------------------------
-.. autoclass:: AsyncConnection
+.. autoclass:: AsyncConnection()
This class implements a DBAPI-inspired interface, with all the blocking
methods implemented as coroutines. Unless specified otherwise,
non-blocking methods are shared with the `Connection` class.
The following methods have the same behaviour of the matching `!Connection`
- methods, but have an `async` interface.
+ methods, but should be called using the `await` keyword.
.. automethod:: connect
.. automethod:: close
- .. note:: you can use `!async with` to close the connection
+ .. note:: you can use ``async with`` to close the connection
automatically when the block is exited, but be careful about
the async quirkness: see :ref:`with-statement` for details.
.. automethod:: cursor
- .. note:: you can use `!async with` to close the cursor
+ .. note:: you can use ``async with`` to close the cursor
automatically when the block is exited, but be careful about
the async quirkness: see :ref:`with-statement` for details.
Connection support objects
--------------------------
-.. autoclass:: Notify
+.. autoclass:: Notify()
:members: channel, payload, pid
+ The objet is usually returned by `Connection.notifies()`.
+
+
.. rubric:: Objects involved in :ref:`transactions`
-.. autoclass:: Transaction(connection: Connection, savepoint_name: Optional[str] = None, force_rollback: bool = False)
+.. autoclass:: Transaction()
.. autoproperty:: savepoint_name
.. autoattribute:: connection
:annotation: Connection
-.. autoclass:: AsyncTransaction(connection: AsyncConnection, savepoint_name: Optional[str] = None, force_rollback: bool = False)
+.. autoclass:: AsyncTransaction()
.. autoexception:: Rollback
The `Cursor` and `AsyncCursor` classes are the main objects to send commands
to a PostgreSQL database session. They are normally created by the
-`~Connection.cursor()` method.
+connection's `~Connection.cursor()` method.
A `Connection` can create several cursors, but only one at time can perform
operations, so they are not the best way to achieve parallelism (you may want
The `!Cursor` class
-------------------
-.. autoclass:: Cursor
+.. autoclass:: Cursor()
This class implements `DBAPI-compliant interface`__. It is what the
classic `Connection.cursor()` method returns. `AsyncConnection.cursor()`
.. automethod:: copy
+ It must be called as ``with cur.copy() as copy: ...``
+
See :ref:`copy` for information about :sql:`COPY`.
.. automethod:: callproc
an exception if used with operations that don't return result, such as an
:sql:`INSERT` with no :sql:`RETURNING` or an :sql:`ALTER TABLE`.
- Cursors are iterable objects, so just using ``for var in cursor`` syntax
- will iterate on the records in the current recordset.
+ .. note:: cursors are iterable objects, so just using ``for record in
+ cursor`` syntax will iterate on the records in the current recordset.
.. automethod:: fetchone
.. automethod:: fetchmany
The `!AsyncCursor` class
------------------------
-.. autoclass:: AsyncCursor
+.. autoclass:: AsyncCursor()
This class implements a DBAPI-inspired interface, with all the blocking
methods implemented as coroutines. Unless specified otherwise,
non-blocking methods are shared with the `Cursor` class.
The following methods have the same behaviour of the matching `!Cursor`
- methods, but have an `async` interface.
+ methods, but should be called using the `await` keyword.
.. automethod:: close
- .. note:: you can use `!async with` to close the cursor
+ .. note:: you can use ``async with`` to close the cursor
automatically when the block is exited, but be careful about
the async quirkness: see :ref:`with-statement` for details.
.. automethod:: execute
.. automethod:: executemany
.. automethod:: copy
+
+ It must be called as ``async with cur.copy() as copy: ...``
+
.. automethod:: callproc
.. automethod:: fetchone
.. automethod:: fetchmany
.. automethod:: fetchall
+ .. note:: you can also use ``async for record in cursor`` to iterate on
+ the async cursor results.
+
Cursor support objects
----------------------
-.. autoclass:: Column
+.. autoclass:: Column()
An object describing a column of data from a database result, `as described
- by the DBAPI`__, so it can also be unpacked as a 7-items tuple
+ by the DBAPI`__, so it can also be unpacked as a 7-items tuple.
+
+ The object is returned by `Cursor.description`.
.. __: https://www.python.org/dev/peps/pep-0249/#description
.. autoproperty:: scale
-.. autoclass:: Copy
+.. autoclass:: Copy()
- The object is normally returned by `Cursor.copy()`. It can be used as a
- context manager (useful to load data into a database using :sql:`COPY FROM`)
- and can be iterated (useful to read data after a :sql:`COPY TO`).
+ The object is normally returned by ``with`` `Cursor.copy()`.
See :ref:`copy` for details.
.. automethod:: read
- Alternatively, you can iterate on the `Copy` object to read its data
- row by row.
+ Instead of using `!read()` you can even iterate on the object to read
+ its data row by row, using ``for row in copy: ...``.
.. automethod:: write
.. automethod:: write_row
see :ref:`adaptation` for details.
-.. autoclass:: AsyncCopy
+.. autoclass:: AsyncCopy()
- The object is normally returned by `AsyncCursor.copy()`. Its methods are
+ The object is normally returned by ``async with`` `AsyncCursor.copy()`. Its methods are
the same of the `Copy` object but offering an `asyncio` interface
(`await`, `async for`, `async with`).
.. automethod:: read
+
+ Instead of using `!read()` you can even iterate on the object to read
+ its data row by row, using ``async for row in copy: ...``.
+
.. automethod:: write
.. automethod:: write_row
.. warning::
- By default even a simple :sql:`SELECT` will start a transaction: in
+ by default even a simple :sql:`SELECT` will start a transaction: in
long-running programs, if no further action is taken, the session will
remain *idle in transaction*, an undesirable condition for several
reasons (locks are held by the session, tables bloat...). For long lived
------------------
A more transparent way to make sure that transactions are finalised at the
-right time is to use `!with` `Connection.transaction()` to create a
+right time is to use ``with`` `Connection.transaction()` to create a
transaction block. When the block is entered a transaction is started; when
leaving the block the transaction is committed, or it is rolled back if an
exception is raised inside the block.
If `!unreliable_operation()` causes an error, including an operation causing a
database error, all its changes will be reverted. The exception bubbles up
-outside the block: in the example it is intercepted by the `!try` so that the
+outside the block: in the example it is intercepted by the ``try`` so that the
loop can complete. The outermost block is unaffected (unless other errors
happen there).
sequences): the Python values are adapted as they would be in normal querying.
To perform such operation use a :sql:`COPY [table] FROM STDIN` with
`Cursor.copy()` and use `~Copy.write_row()` on the resulting object in a
-`!with` block. On exiting the block the operation will be concluded:
+``with`` block. On exiting the block the operation will be concluded:
.. code:: python
"""Manage a :sql:`COPY` operation."""
def read(self) -> bytes:
- """Read a row after a :sql:`COPY TO` operation.
+ """Read a row of data after a :sql:`COPY TO` operation.
Return an empty bytes string when the data is finished.
"""
return b""
def write(self, buffer: Union[str, bytes]) -> None:
- """Write a block of data after a :sql:`COPY FROM` operation."""
+ """Write a block of data after a :sql:`COPY FROM` operation.
+
+ If the COPY is in binary format *buffer* must be `!bytes`. In text mode
+ it can be either `!bytes` or `!str`.
+ """
conn = self.connection
conn.wait(copy_to(conn.pgconn, self._ensure_bytes(buffer)))