游标类
Cursor
和AsyncCursor
类是将命令发送到 PostgreSQL 数据库会话的主要对象。它们通常由连接的cursor()
方法创建。
使用cursor()
方法的name
参数将创建一个ServerCursor
或AsyncServerCursor
,可用于从数据库中检索部分结果。
一个Connection
可以创建多个游标,但同一时间只能有一个游标可以执行操作,因此它们不是实现并行性的最佳方式(您可能希望改为使用多个连接进行操作)。同一连接上的所有游标都具有同一会话的快照,因此它们可以看到彼此的未提交数据。
class psycopg.Cursor(connection, *, row_factory=None)
此类实现了符合 DBAPI 的接口。这是经典的Connection.cursor()
方法返回的类型。AsyncConnection.cursor()
将会创建AsyncCursor
对象,该对象和Cursor
具有相同的方法集,但公开了一个asyncio
接口并需要async
和await
关键字才能运行。
游标以上下文管理器的形式出现时:在代码块退出时,它们被关闭,无法进一步操作。但是,关闭游标不会终止事务或会话。
connection: Connection
此游标正在使用的连接。
close()
关闭当前游标并释放关联的资源。
closed
如果游标已关闭,则为 True
。
发送命令的方法
execute(query, params=None, *, prepare=None, binary=None)
对数据库执行查询或命令。
返回类型:
TypeVar
(_Self
, bound= Cursor[Any])
参数:
- query (!str, !bytes, sql.SQL, 或 sql.Composed) – 要执行的查询。
- params (序列 或 映射) – 要传递给查询的参数(如果有)。
- prepare – 强制 (!True)或不允许 (!False)使用预备查询。默认情况下(!None)会自动进行预备查询。请参阅预备语句。
- binary – 指定服务器是否应以二进制格式(!True)或文本格式(!False)返回数据。默认情况下(!None)会按照游标的 ~Cursor.format 指定的格式返回数据。
返回游标本身,以便可以在调用后链接读取操作。
有关执行查询的所有详细信息,请参阅将参数传递给 SQL 查询。
在 3.1 版本更改: 查询参数必须是 ~typing.StringLiteral。如果您需要动态编写查询,请使用 sql.SQL 和相关对象。
有关详细信息,请参阅 PEP 675。
executemany(query, params_seq, *, returning=False)
使用一系列输入数据执行相同的命令。
参数:
- query (!str, !bytes, sql.SQL, 或 sql.Composed) – 要执行的查询
- params_seq (序列或映射的序列) – 要传递给查询的参数
- returning (!bool) – 如果是 !True,获取执行的查询的结果
这比执行单独的查询更有效,但是在多个INSERT
的情况下(并且对于大量UPDATE
也有一些SQL创造力),您可以考虑使用 copy()。
如果查询返回要读取的数据(例如,在执行具有副作用的INSERT ... RETURNING
或SELECT
时),您可以指定 !returning=True;结果将在游标状态下可用,可以使用 fetchone() 和类似方法读取。每个输入参数将生成一个单独的结果集:可用使用 nextset() 依次读取第一个查询之后的查询结果。
rowcount 的值设置为受查询影响的累计行数;除非使用 !returning=True,在这种情况下,它被设置为当前结果集中的行数(即第一个查询结果集,直到 nextset() 被调用)。
有关执行查询的所有详细信息,请参阅将参数传递给 SQL 查询。
在 3.1 版本更改:
- 新增 !returning 参数,用于接收查询结果。
- 使用 libpq 14 或更高版本时,通过使用流水线模式优化了性能。
copy(statement, params=None, *, writer=None)
启动一次COPY
操作并返回一个对象来管理它。
返回类型:
参数:
- statement (!str, !bytes, sql.SQL, 或 sql.Composed) – 要执行的复制操作
- params (序列或映射) – 要传递给语句的参数(如果有)。
必须使用以下命令调用该方法:
with cursor.copy() as copy: ...
有关COPY
的信息,请参阅使用 COPY TO 和 COPY FROM。
*在 3.1 版本更改:*添加了参数支持。
stream(query, params=None, *, binary=None)
逐行循环访问数据库中的结果。
返回类型:
Iterator
[TypeVar
(Row
, covariant=True)]
此命令类似于执行 + 迭代;但是它支持无休止的数据流。该功能在 PostgreSQL 中不可用,但存在一些实现:例如 Materialize 的 SUBSCRIBE 和 CockroachDB 的 CHANGEFEED。
该功能和支持它的 API 仍处于实验阶段。小心。。。👀
参数与 execute() 相同。
Failing to consume the iterator entirely will result in a connection left in ~psycopg.ConnectionInfo.transaction_status ~pq.TransactionStatus.ACTIVE state: this connection will refuse to receive further commands (with a message such as another command is already in progress).
If there is a chance that the generator is not consumed entirely, in order to restore the connection to a working state you can call ~generator.close on the generator object returned by !stream(). The contextlib.closing function might be particularly useful to make sure that !close() is called:
with closing(cur.stream("select generate_series(1, 10000)")) as gen: for rec in gen: something(rec) # might fail
Without calling !close(), in case of error, the connection will be !ACTIVE and unusable. If !close() is called, the connection might be !INTRANS or !INERROR, depending on whether the server managed to send the entire resultset to the client. An autocommit connection will be !IDLE instead.
format
查询返回的数据的格式。它可以选择初始格式,例如指定 Connection.cursor!(binary=True) 并在游标的生存期内更改。也可以覆盖单个查询的数据格式,例如指定 execute!(binary=True)。
类型:
pq.Format
默认值:
~pq.Format.TEXT
检索结果的方法
仅当最后一个操作产生结果时,fetch 方法才可用,例如一条SELECT
或带有RETURNING
的命令。如果与不返回结果的操作一起使用,它们将会产生异常,例如一条不带RETURNING
的INSERT
或一个ALTER TABLE
操作。
游标是可迭代的对象,因此只需使用:
for record in cursor: ...
语法将循环访问当前记录集中的记录。
row_factory
可写属性,用于控制结果行的形成方式。
该属性会影响由 fetchone()、fetchmany()、fetchall() 方法返回的对象。默认值(~psycopg.rows.tuple_row)为获取的每条记录返回一个元组。
有关详细信息,请参阅行工厂。
fetchone()
返回当前记录集中的下一条记录。
记录集完成获取后返回 !None。
返回类型:
可选[行],行由 row_factory 定义
fetchmany(size=0)
从当前记录集中返回下一批 !size 数目的记录。
如果未指定,则 !size 默认为 !self.arraysize。
返回类型:
序列[行],行由 row_factory 定义
fetchall()
返回当前记录集中的所有剩余记录。
返回类型:
序列[行],行由 row_factory 定义
nextset()
移动到通过 executemany() 执行的下一个查询的结果集,或者移动到通过 execute() 返回的多个结果集中的下一个结果集。
如果有新的可用结果,则返回 !True,这将是 !fetch*() 方法将对其执行操作的结果集。
返回类型:
scroll(value, mode='relative')
根据模式将结果集中的游标移动到新位置。
如果 !mode 为'relative'
(默认值),则 !value 将作为结果集中当前位置的偏移量;如果设置为'absolute'
,!value 表示绝对目标位置。
滚动操作将要离开结果集时,抛出 !IndexError 异常。在这种情况下,游标位置不会改变。
pgresult: Optional[psycopg.pq.PGresult]
如果存在可用的结果,它表示由最后一个查询返回且当前由游标公开的结果,否则为 !None。
它可用于获取有关上次查询结果的底层信息,并访问当前未由 Psycopg 包装的功能。
有关数据的信息
description
描述当前结果集的 Column 对象列表。
如果当前结果集未返回元组,则为 !None。
statusmessage
上次执行的 SQL 命令中的命令状态标记。
如果游标没有可用的结果,则为 !None。
这是您通常在 psql 中成功执行命令后看到的状态标记,例如CREATE TABLE
或UPDATE 42
。
rowcount
受执行操作影响的记录数。
对于 executemany() 方法,除非使用 !returning=True 调用,否则这是受已执行命令影响的累积行数。
rownumber
要在当前结果中获取的下一行的索引。
如果没有要获取的结果,则为 !None。
_query
一个辅助对象,用于在将查询和参数发送到 PostgreSQL 之前对其进行转换。
此属性之所以公开,是因为当 Python 和 PostgreSQL 之间的通信无法按预期工作时,调试问题可能会有所帮助。因此,当查询失败时,该属性也可用。
如果您想使用此对象构建可靠的功能,请与我们联系,以便我们可以尝试为其设计一个有用的接口。
您不应将其视为对象公共接口的一部分:它可能会在没有警告的情况下发生改变。
除了这个警告,我猜。
在此对象当前公开的属性中:
- !query (!bytes): 有效地发送到 PostgreSQL 的查询。它将把 Python 占位符(
%s
-形式)替换为 PostgreSQL 占位符($1
,$2
-形式)。 - !params (!bytes 序列): 传递给 PostgreSQL 的参数,参数要适配数据库格式。
- !types (!int 序列): 传递给 PostgreSQL 的参数的类型 OID。
- !formats (pq.Format 序列): 参数格式是文本还是二进制。
See Client-side-binding cursors for details.
class psycopg.ClientCursor(connection, *, row_factory=None)
This Cursor subclass has exactly the same interface of its parent class, but, instead of sending query and parameters separately to the server, it merges them on the client and sends them as a non-parametric query on the server. This allows, for instance, to execute parametrized data definition statements and other problematic queries.
New in version 3.1.
mogrify(query, params=None)
Return the query and parameters merged.
Parameters are adapted and merged to the query the same way that !execute() would do.
返回类型:
参数:
- query (!str, !bytes, sql.SQL, or sql.Composed) – The query to execute.
- params (Sequence or Mapping) – The parameters to pass to the query, if any.
See Server-side cursors for details.
class psycopg.ServerCursor(connection, name, *, row_factory=None, scrollable=None, withhold=False)
This class also implements a DBAPI-compliant interface. It is created by Connection.cursor() specifying the !name parameter. Using this object results in the creation of an equivalent PostgreSQL cursor in the server. DBAPI-extension methods (such as ~Cursor.copy() or ~Cursor.stream()) are not implemented on this object: use a normal Cursor instead.
Most attribute and methods behave exactly like in Cursor, here are documented the differences:
name
The name of the cursor.
scrollable
Whether the cursor is scrollable or not.
If !None leave the choice to the server. Use !True if you want to use scroll() on the cursor.
PostgreSQL DECLARE 语句文档中描述[NO] SCROLL
的部分。
withhold
If the cursor can be used after the creating transaction has committed.
PostgreSQL DECLARE 语句文档中描述{WITH|WITHOUT} HOLD
的部分。
close()
Close the current cursor and free associated resources.
Closing a server-side cursor is more important than closing a client-side one because it also releases the resources on the server, which otherwise might remain allocated until the end of the session (memory, locks). Using the pattern:
with conn.cursor(): ...
is especially useful so that the cursor is closed at the end of the block.
execute(query, params=None, *, binary=None, **kwargs)
Open a cursor to execute a query to the database.
返回类型:
TypeVar
(_Self
, bound= ServerCursor[Any])
参数:
- query (!str, !bytes, sql.SQL, or sql.Composed) – The query to execute.
- params (Sequence or Mapping) – The parameters to pass to the query, if any.
- binary – Specify whether the server should return data in binary format (!True) or in text format (!False). By default (!None) return data as requested by the cursor’s ~Cursor.format.
Create a server cursor with given !name and the !query in argument.
If using DECLARE
is not appropriate (for instance because the cursor is returned by calling a stored procedure) you can avoid to use !execute(), crete the cursor in other ways, and use directly the !fetch*() methods instead. See “Stealing” an existing cursor for an example.
Using !execute() more than once will close the previous cursor and open a new one with the same name.
executemany(query, params_seq, *, returning=True)
Method not implemented for server-side cursors.
fetchone()
Return the next record from the current recordset.
Return !None the recordset is finished.
返回类型:
Optional[Row], with Row defined by row_factory
fetchmany(size=0)
Return the next !size records from the current recordset.
!size default to !self.arraysize if not specified.
返回类型:
Sequence[Row], with Row defined by row_factory
fetchall()
Return all the remaining records from the current recordset.
返回类型:
Sequence[Row], with Row defined by row_factory
这些方法使用 FETCH SQL 语句从游标的当前位置检索一些记录。
You can also iterate on the cursor to read its result one at time with:
for record in cur: ...
In this case, the records are not fetched one at time from the server but they are retrieved in batches of itersize to reduce the number of server roundtrips.
itersize: int
Number of records to fetch at time when iterating on the cursor. The default is 100.
scroll(value, mode='relative')
Move the cursor in the result set to a new position according to mode.
If !mode is 'relative'
(default), !value is taken as offset to the current position in the result set; if set to 'absolute'
, !value states an absolute target position.
Raise !IndexError in case a scroll operation would leave the result set. In this case the position will not change.
此方法使用 MOVE SQL 语句移动服务端游标中的当前位置,这将影响后续的 !fetch*() 操作。如果你需要向后滚动,你应该使用 scrollable=True 调用 ~Connection.cursor()。
Note that PostgreSQL doesn’t provide a reliable way to report when a cursor moves out of bound, so the method might not raise !IndexError when it happens, but it might rather stop at the cursor boundary.
class psycopg.AsyncCursor(connection, *, row_factory=None)
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 should be called using the await keyword.
connection: AsyncConnection
async close()
You can use:
async with conn.cursor(): ...
to close the cursor automatically when the block is exited.
async execute(query, params=None, *, prepare=None, binary=None)
返回类型:
TypeVar
(_Self
, bound= AsyncCursor[Any])
async executemany(query, params_seq, *, returning=False)
copy(statement, params=None, *, writer=None)
返回类型:
The method must be called with:
async with cursor.copy() as copy: ...
async stream(query, params=None, *, binary=None)
返回类型:
AsyncIterator
[TypeVar
(Row
, covariant=True)]
The method must be called with:
async for record in cursor.stream(query): ...
async fetchone()
返回类型:
Optional
[TypeVar
(Row
, covariant=True)]
async fetchmany(size=0)
返回类型:
List
[TypeVar
(Row
, covariant=True)]
async fetchall()
返回类型:
List
[TypeVar
(Row
, covariant=True)]
async scroll(value, mode='relative')
You can also use:
async for record in cursor: ...
to iterate on the async cursor results.
class psycopg.AsyncClientCursor(connection, *, row_factory=None)
This class is the !async equivalent of the ClientCursor. The difference are the same shown in AsyncCursor.
New in version 3.1.
class psycopg.AsyncServerCursor(connection, name, *, row_factory=None, scrollable=None, withhold=False)
This class implements a DBAPI-inspired interface as the AsyncCursor does, but wraps a server-side cursor like the ServerCursor class. It is created by AsyncConnection.cursor() specifying the !name parameter.
The following are the methods exposing a different (async) interface from the ServerCursor counterpart, but sharing the same semantics.
async close()
You can close the cursor automatically using:
async with conn.cursor("name") as cursor: ...
async execute(query, params=None, *, binary=None, **kwargs)
返回类型:
TypeVar
(_Self
, bound= AsyncServerCursor[Any])
async executemany(query, params_seq, *, returning=True)
async fetchone()
返回类型:
Optional
[TypeVar
(Row
, covariant=True)]
async fetchmany(size=0)
返回类型:
List
[TypeVar
(Row
, covariant=True)]
async fetchall()
返回类型:
List
[TypeVar
(Row
, covariant=True)]
您还可以使用以下方法对游标进行迭代:
async for record in cur: ...
async scroll(value, mode='relative')