python - 如何在 psycopg2 中使用服务器端游标

标签 python postgresql psycopg2 database-cursor

我有一个包含 400 万行的表,我使用 psycopg2 执行:

   SELECT * FROM ..WHERE query

我以前从未听说过服务器端游标,我正在阅读它是一种在您期望获得大量结果时的良好做法。

我发现文档有些局限,而且我有一些基本问题。

首先我将服务器端游标声明为:

cur = conn.cursor('cursor-name')

然后我执行查询:

cur.itersize = 10000
sqlstr = "SELECT clmn1, clmn2 FROM public.table WHERE clmn1 LIKE 'At%'"
cur.execute(sqlstr)

我的问题是:我现在该怎么办?我如何获得结果?

我是否按以下方式遍历行:

row = cur.fetchone()
while row:
   row = cur.fetchone()

或者我使用 fetchmany() 并这样做:

row = cur.fetchmany(10)

但是在第二种情况下,我怎样才能“滚动”结果呢?

itersize 的意义何在?

最佳答案

Psycopg2 有一个很好的界面来处理服务器端游标。这是一个可能使用的模板:

with psycopg2.connect(database_connection_string) as conn:
    with conn.cursor(name='name_of_cursor') as cursor:
    
        cursor.itersize = 20000

        query = "SELECT * FROM ..."
        cursor.execute(query)

        for row in cursor:
            # process row 

上面的代码创建连接并自动将查询结果放入服务器端游标。值itersize设置客户端一次从服务器端游标中拉下的行数。您使用的值应该平衡网络调用的数量与客户端上的内存使用量。例如,如果您的结果计数为三百万,则 itersize 值为 2000(默认值)将导致 1500 次网络调用。如果 2000 行消耗的内存较少,则增加该数字。

当使用 for row in cursor 时,您当然是一次处理一行,但 Psycopg2 将为您一次预取 itersize 行。

如果出于某种原因你想使用fetchmany,你可以这样做:

while True:
    rows = cursor.fetchmany(100)
    if len(rows) > 0:
        for row in rows:
            # process row
    else:
        break

fetchmany 的这种用法不会触发对服务器的网络调用以获取更多行,直到预取的批处理用完为止。 (这是一个复杂的示例,上面的代码没有提供任何内容,但演示了如何在需要时使用 fetchmany。)

关于python - 如何在 psycopg2 中使用服务器端游标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41444890/

相关文章:

Python IDLE 无法工作,因为缺少 python.exe

java - WildFly 9.0 如何添加 PostgreSQL 数据源?

python - Kubernetes部署,如何解决: psycopg2. OperationalError : SCRAM authentication requires libpq version 10 or above?

python - 在 Postgres 中存储 JSON 时保留 Python None/NULL

postgresql - 访问启动触发器的行

python - SQLAlchemy:引擎、连接和 session 的区别

postgresql - 向 Postgres 进行身份验证时如何使用自定义密码哈希算法?

python - 从 Python 调用 OpenGL 扩展

Python 多索引 : Finding cordinates with level 2 index, DataFrame

python - 密码重置功能 django 中的 NoReverseMatch 错误