如何使用pyscopg2的异步功能?

Rah*_*hul 6 postgresql asynchronous postgis psycopg2

我正在尝试使用不同的表执行 3 个不同的 postgresql 查询。每个查询需要 2 秒来执行。我想知道是否可以同时运行所有 3 个查询,以便我可以节省 4 秒。我尝试使用的异步功能,pyscopg2但它只返回上次查询的结果。谁能指出我做错了什么?

import select
import psycopg2
import psycopg2.extensions

def wait(conn):
    while 1:
        state = conn.poll()
        if state == psycopg2.extensions.POLL_OK:
            break
        elif state == psycopg2.extensions.POLL_WRITE:
            select.select([], [conn.fileno()], [])
        elif state == psycopg2.extensions.POLL_READ:
            select.select([conn.fileno()], [], [])
        else:
            raise psycopg2.OperationalError("poll() returned %s" % state)


aconn = psycopg2.connect(
  dbname=pg_name,
  user=pg_username,
  host=pg_host,
  password=pg_password,
  async=1)

wait(aconn)
acurs = aconn.cursor()

acurs.execute(
              "SELECT 1;"
              "SELECT ST_Length(ST_GeomFromText"
              "('LINESTRING(743238 2967416,743238 2967450)',4326));"
              "SELECT 3;"
             )
wait(acurs.connection)
result = acurs.fetchall()
print result
Run Code Online (Sandbox Code Playgroud)

这只会打印:“结果”:[[3]]

vil*_*apx 5

根据 Psycopg介绍:

[Psycopg] 是 PostgreSQL 官方客户端库 libpq 的包装器。

然后,看着libpq 文档的PQexec()(函数用来发送SQL查询到PostgreSQL数据库),我们可以看到下面的注释(重点煤矿):

在单个 PQexec 调用中发送的多个查询在单个事务中处理,除非查询字符串中包含显式 BEGIN/COMMIT 命令以将其划分为多个事务。但是请注意,返回的 PGresult 结构仅描述从字符串执行的最后一个命令的结果。

所以,不幸的是,你想要做的根本不支持psycopg2和libpq。(这并不是说 PostgreSQL 的其他客户端接口不支持它,但这超出了这个问题的范围。)

因此,要回答您的问题,您做错的是在一次execute()调用中执行多个 SQL 查询,然后尝试检索所有结果,而实际上这是不可能的。您需要显式执行每个查询并单独检索结果,或者尝试找到另一个支持一次返回多个结果集的 PostgreSQL API。


Python 数据库 API 2.0 规范确实允许nextset()库实现可选方法,该方法将 移动cursor到从执行的查询返回的下一个结果集,但此方法未在psycopg2(出于显而易见的原因)中实现,实际上引发了NotSupportedError异常如果您尝试调用它(请参阅文档)。