:type query: `!str`, `!bytes`, or `sql.Composable`
:param params_seq: The parameters to pass to the query
:type params_seq: Sequence of Sequences or Mappings
- :param returning: If `!false`, query results won't be available to fetch
+ :param returning: If `!True`, fetch the results of the queries executed
:type returning: `!bool`
This is more efficient than performing separate queries, but in case of
several :sql:`INSERT` (and with some SQL creativity for massive
:sql:`UPDATE` too) you may consider using `copy()`.
- If the queries return data (e.g. when executing an :sql:`INSERT ...
- RETURNING` or a :sql:`SELECT` with a side-effect), the result will be
- available in the cursor's state, using `fetchone()` and similar
- methods; results after the first will be available using `nextset()`.
- In case this makes use of an unacceptable amount of memory you can use
- `!returning=False` to disable returning the results. This is not
- necessary if the queries return no data (e.g. on :sql:`INSERT` without
- returning).
+ If the queries return data you want to read (e.g. when executing an
+ :sql:`INSERT ... RETURNING` or a :sql:`SELECT` with a side-effect),
+ you can specify ``returning=True``; the results will be available in
+ the cursor's state and can be read using `fetchone()` and similar
+ methods. Each input parameter will produce a separate result set: use
+ `nextset()` to read the results of the queries after the first one.
See :ref:`query-parameters` for all the details about executing
queries.
.. versionchanged:: 3.1
- results are now available in the cursor state, added `!returning`
- parameter to disable it.
+ added ``returning`` parameter to receive query results.
.. automethod:: copy
^^^^^^^^^^^^^^^^^^^^^^^^
- Add :ref:`Two-Phase Commit <two-phase-commit>` support (:ticket:`#72`).
-- Return results from all queries run through `~Cursor.executemany()`; each
- result set can be accessed by calling `~Cursor.nextset()` (:ticket:`#164`).
+- Add ``returning`` parameter to `~Cursor.executemany()` to retrieve query
+ results (:ticket:`#164`).
- Add `pq.PGconn.trace()` and related trace functions (:ticket:`#167`).
- Add ``prepare_threshold`` parameter to `Connection` init (:ticket:`#200`).
- Add `Error.pgconn` and `Error.pgresult` attributes (:ticket:`#242`).
query: Query,
params_seq: Iterable[Params],
*,
- returning: bool = True,
+ returning: bool = False,
) -> None:
"""
Execute the same command with a sequence of input data.
query: Query,
params_seq: Iterable[Params],
*,
- returning: bool = True,
+ returning: bool = False,
) -> None:
try:
async with self._conn.lock:
cur.executemany(
"insert into execmany(num, data) values (%s, %s) returning num",
[(10, "hello"), (20, "world")],
+ returning=True,
)
assert cur.rowcount == 2
assert cur.fetchone() == (10,)
cur.executemany(
"insert into execmany(num, data) values (%s, %s) returning num",
[(10, "hello"), (20, "world")],
- returning=False,
)
assert cur.rowcount == 2
with pytest.raises(psycopg.ProgrammingError):
cur.executemany(
"insert into execmany(num, data) values (%s, %s)",
[(10, "hello"), (20, "world")],
+ returning=True,
)
assert cur.rowcount == 2
with pytest.raises(psycopg.ProgrammingError):
await cur.executemany(
"insert into execmany(num, data) values (%s, %s) returning num",
[(10, "hello"), (20, "world")],
+ returning=True,
)
assert cur.rowcount == 2
assert (await cur.fetchone()) == (10,)
await cur.executemany(
"insert into execmany(num, data) values (%s, %s) returning num",
[(10, "hello"), (20, "world")],
- returning=False,
)
assert cur.rowcount == 2
with pytest.raises(psycopg.ProgrammingError):
await cur.executemany(
"insert into execmany(num, data) values (%s, %s)",
[(10, "hello"), (20, "world")],
+ returning=True,
)
assert cur.rowcount == 2
with pytest.raises(psycopg.ProgrammingError):