如何使用pyscopg2的异步功能?

时间:2016-07-24 02:38:26

标签: 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

仅打印:“结果”:[[3]]

2 个答案:

答案 0 :(得分:1)

根据Psycopg Introduction

  

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

然后,查看libpq PQexec() psycopg2(用于将SQL查询发送到PostgreSQL数据库的函数),我们看到以下注释(强调我的):

  

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

所以,遗憾的是,libpqexecute()并不支持您尝试做的事情。 (这并不是说PostgreSQL的其他客户端接口不支持它,但这超出了这个问题的范围。)

所以为了回答你的问题,你所做错的是在一次cursor调用中执行多个SQL查询并尝试事后检索所有的结果,而事实上它并非如此可能。您需要显式执行每个查询并单独检索结果,否则尝试找到支持一次返回多个结果集的PostgreSQL的另一个API。

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

答案 1 :(得分:1)

看起来它现在从 2.2 版开始支持

each

来源:https://www.psycopg.org/docs/advanced.html#asynchronous-support