Skip to content

Commit 2c34151

Browse files
committed
Tidy up docs
1 parent 69d2e74 commit 2c34151

1 file changed

Lines changed: 51 additions & 35 deletions

File tree

docs/peewee/postgres.rst

Lines changed: 51 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -74,16 +74,23 @@ you must use :class:`PostgresqlExtDatabase`.
7474

7575
.. _psycopg2-vs-psycopg3:
7676

77-
psycopg2 versus psycopg3
78-
------------------------
77+
psycopg2 vs psycopg3
78+
--------------------
7979

80-
Peewee supports both drivers and uses psycopg2 when both are installed,
81-
unless ``prefer_psycopg3`` is given. Queries generated by peewee behave
82-
identically on either. The difference is in how hand-written SQL is bound:
83-
psycopg2 interpolates parameters into the query string on the client,
84-
psycopg3 sends the query and parameters separately and Postgres binds them.
85-
Server-side binding only accepts parameters in value positions of a single
86-
plannable statement:
80+
Peewee supports both drivers, and will use whichever is installed. If **both**
81+
psycopg2 and psycopg(3) are installed, Peewee defaults to psycopg2 unless
82+
``prefer_psycopg3=True`` is specified:
83+
84+
.. code-block:: python
85+
86+
# If both psycopg2 and psycopg3 are installed, use psycopg3.
87+
db = PostgresqlDatabase('peewee_test', prefer_psycopg3=True)
88+
89+
Queries generated by peewee behave identically on either. The difference is in
90+
how hand-written SQL is bound: psycopg2 interpolates parameters into the query
91+
string on the client, while psycopg3 sends the query and parameters separately
92+
and Postgres binds them. psycopg3's server-side binding only accepts parameters
93+
in value positions within a single query:
8794

8895
.. code-block:: python
8996
@@ -103,8 +110,8 @@ passing psycopg's ``ClientCursor``:
103110
104111
import psycopg
105112
106-
db = PostgresqlExtDatabase('my_app', prefer_psycopg3=True,
107-
cursor_factory=psycopg.ClientCursor)
113+
db = PostgresqlDatabase('my_app', prefer_psycopg3=True,
114+
cursor_factory=psycopg.ClientCursor)
108115
109116
In exchange, psycopg3 automatically promotes frequently-executed queries to
110117
server-side prepared statements, skipping repeated parse and plan overhead.
@@ -985,18 +992,17 @@ For more information, see the `Postgres full-text search docs <https://www.postg
985992
Server-Side Cursors
986993
-------------------
987994

988-
For large result sets, server-side (named) cursors stream rows from the server
989-
rather than loading the entire result into memory. Rows are fetched
995+
For large result sets, server-side (or named) cursors stream rows from the
996+
server rather than loading the entire result into memory. Rows are fetched
990997
transparently from the server as you iterate. A regular cursor, by contrast,
991-
buffers the complete result set on the client at execute time, even when
992-
iterating with :meth:`~BaseQuery.iterator`.
998+
buffers the complete result set on the client at execute time.
993999

9941000
Refer to your driver documentation for details:
9951001

9961002
* `psycopg2 server-side cursors <https://www.psycopg.org/docs/usage.html#server-side-cursors>`__
9971003
* `psycopg3 server-side cursors <https://www.psycopg.org/psycopg3/docs/advanced/cursors.html#server-side-cursors>`__
9981004

999-
To use server-side (or named) cursors, you must be using :class:`PostgresqlExtDatabase`.
1005+
To use server-side cursors, you must be using :class:`PostgresqlExtDatabase`.
10001006

10011007
Wrap any SELECT query with :func:`ServerSide`:
10021008

@@ -1019,30 +1025,40 @@ Wrap any SELECT query with :func:`ServerSide`:
10191025
10201026
Rows are fetched from the server in batches of ``array_size``, which defaults
10211027
to the driver's ``itersize`` (2000 with psycopg2, 100 with psycopg3). For
1022-
large scans specify ``array_size`` explicitly.
1028+
large scans specify ``array_size`` explicitly:
1029+
1030+
.. code-block:: python
10231031
1024-
A named cursor is ordinarily bound to a transaction and is destroyed when the
1025-
transaction ends. Declaring it ``WITH HOLD`` lets it outlive the transaction.
1026-
The server pays for this at commit by copying the cursor's remaining rows
1027-
into temporary storage, and later fetches read from that copy. Peewee
1028-
connections autocommit, so a ``WITH HOLD`` cursor opened outside a
1032+
for page_view in ServerSide(large_query, array_size=1000):
1033+
# Do something interesting.
1034+
pass
1035+
1036+
Ordinarily, a server-side cursor is bound to a transaction and is destroyed when the
1037+
transaction ends. To use a server-side cursor outside a transaction, it must be
1038+
declared ``WITH HOLD``, which has a couple consequences:
1039+
1040+
* Server has to copy the cursor's rows into temporary storage upon commit, so
1041+
subsequent fetches read from the frozen copy.
1042+
* Cursor must be exhausted or explicitly closed in order to release the held
1043+
resources.
1044+
1045+
Peewee connections autocommit, so a ``WITH HOLD`` cursor opened outside a
10291046
transaction is committed at once and materializes the entire result set
10301047
before the first row arrives. Inside a transaction nothing is copied and
10311048
rows stream on demand.
10321049

1033-
Peewee declares ``WITH HOLD`` only when it has to. With psycopg3, a cursor
1034-
opened inside a transaction is a plain named cursor. It streams, commit is
1035-
instant, and the cursor ends with the transaction. Iterating after the
1036-
transaction closes raises ``InvalidCursorName``. psycopg2 does not allow
1037-
plain named cursors on autocommit connections, so peewee always declares
1038-
``WITH HOLD`` there. Inside a transaction such a cursor streams all the same,
1039-
but if it is still open when the transaction commits, the remaining rows are
1040-
copied and the cursor survives.
1041-
1042-
Iterate inside a transaction when you can. Use a cursor with no transaction
1043-
when the iteration is too long to hold one open, and accept the up-front
1044-
materialization. When the result fits in client memory, a regular cursor is
1045-
simpler still.
1050+
Peewee declares ``WITH HOLD`` only when it has to:
1051+
1052+
* psycopg3: server-side cursors opened inside a transaction do not specify
1053+
``WITH HOLD``. The cursor streams normally and the cursor ends with the
1054+
transaction. Iterating after the transaction closes will raise ``InvalidCursorName``.
1055+
* psycopg2 does not allow server-side cursors on autocommit connections, so
1056+
peewee always declares ``WITH HOLD`` on psycopg2. Inside a transaction such a
1057+
cursor streams normally, but if it is still open when the transaction
1058+
commits, the remaining rows are copied and the cursor and resources survive.
1059+
1060+
Use server-side cursors inside a transaction whenever possible. When the result
1061+
fits in client memory, a regular (non-server-side) cursor is preferable.
10461062

10471063
.. list-table::
10481064
:header-rows: 1

0 commit comments

Comments
 (0)