服务器端游标的 Psycopg2 行数

Psycopg2 rowcount for server side cursor

我正在查询 Postgres 数据库以获得大量结果,并希望使用服务器端游标将结果流式传输到我的客户端。看起来当我这样做时,光标的 rowcount 属性现在在我执行查询后设置为 -1。我正在这样创建光标:

with db.cursor('cursor_name') as cursor:

有没有办法在从数据库流式传输结果时查找查询结果的数量? (我可以做 SELECT COUNT(*),但我想避免这样做,因为我试图抽象出查询周围的代码,这会使 API 复杂化)。

在服务器端游标的情况下,尽管 cursor.execute() returns,此时服务器不一定执行查询,因此行数不可用于psycopg2。这与 DBAPI 2.0 spec 一致,它指出如果最后一个操作的行数不确定,rowcount 应该是 -1。

尝试用 cursor.fetchone() 强制它,例如,更新 cursor.rowcount,但仅限于检索到的项目数,因此这没有用。 cursor.fetchall() 将导致 rowcount 被正确设置,但是,这会执行您试图避免的完整查询和数据传输。

一个可能的解决方法是:

select *, (select count(*) from test) from test;

这将导致每行的最后一列附加 table 行计数。然后,您可以使用 cursor.fetchone() 获取 table 行数,然后获取最后一列:

with db.cursor('cursor_name') as cursor:
    cursor.execute('select *, (select count(*) from test) from test')
    row = cursor.fetchone()
    data, count = row[:-1], row[-1]

现在 count 将包含 table 中的行数。您可以使用 row[:-1] 来引用行数据。

这可能会减慢查询速度,因为可能会执行昂贵的 SELECT COUNT(*),但一旦完成检索数据应该很快。