From f2d108a913b0421d6131604be8a56f87553d2ee9 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Martin=20Bal=C3=A1=C5=BE?= Date: Fri, 9 May 2025 12:10:05 +0200 Subject: [PATCH] docs: document Cursor.results() and add rease note --- docs/api/cursors.rst | 29 +++++++++++++++++++++++------ docs/news.rst | 3 +++ 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/docs/api/cursors.rst b/docs/api/cursors.rst index 826b568f0..bcf03a894 100644 --- a/docs/api/cursors.rst +++ b/docs/api/cursors.rst @@ -122,17 +122,13 @@ The `!Cursor` class using a pattern such as:: cur.executemany(query, records) - ids = [] - while True: - ids.append(cur.fetchone()[0]) - if not cur.nextset(): - break + ids = [cur.fetchone()[0] for _ in cur.results()] .. warning:: More explicitly, `!fetchall()` alone will not return all the values returned! You must iterate on the results using - `!nextset()`. + `!results()`. If `!returning=False`, the value of `rowcount` is set to the cumulated number of rows affected by queries. If `!returning=True`, `!rowcount` @@ -266,6 +262,26 @@ The `!Cursor` class .. automethod:: fetchmany .. automethod:: fetchall .. automethod:: nextset + .. automethod:: results + + The iterator yields the cursor itself upon iteration, but the cursor + state changes, in a way equivalent to calling `nextset()` in a loop. + Therefore you can ignore the result of the iteration if you are consuming + `!results()` in a loop:: + + for _ in cursor.results(): + for row in cursor: + ... + + or make use of it for example using `map()` to consume the iterator:: + + def cursor_consumer(cur: Cursor) -> Any: + ... + + map(cursor_consumer, cursor.results()) + + .. versionadded:: 3.3 + .. automethod:: scroll .. attribute:: pgresult @@ -538,6 +554,7 @@ semantic with an `!async` interface. The main interface is described in .. automethod:: fetchone .. automethod:: fetchmany .. automethod:: fetchall + .. automethod:: results .. automethod:: scroll .. note:: diff --git a/docs/news.rst b/docs/news.rst index 121d3b9ed..ea4e65df9 100644 --- a/docs/news.rst +++ b/docs/news.rst @@ -16,6 +16,9 @@ Psycopg 3.3.0 (unreleased) - Cursors are now iterators, not only iterables. This means you can call ``next(cur)`` to fetch the next row (:ticket:`#1064`). - Drop support for Python 3.8 (:ticket:`#976`) and 3.9 (:ticket:`#1056`). +- Add `Cursor.results()` to iterate over the result sets of the queries + executed though `~Cursor.executemany()` or `~Cursor.execute()` + (:ticket:`#1080`). Psycopg 3.2.10 (unreleased) -- 2.47.2