2016-07-24 2 views
1

Я пытаюсь выполнить 3 разных запроса postgresql с другой таблицей. Для выполнения каждого запроса требуется 2 секунды. Мне было интересно, можно ли одновременно запускать все 3 запроса, чтобы я мог сэкономить 4 секунды. Я попытался использовать асинхронную функцию pyscopg2, но она возвращает результат последнего запроса. Может ли кто-нибудь указать, что я делаю неправильно?Как использовать асинхронную функцию 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]]

ответ

0

согласно Psycopg Introduction:

[Psycopg] является оболочкой для libpq, официальной библиотеки PostgreSQL клиента ,

Затем, глядя на libpqdocumentation для PQexec() (функция используется для отправки запросов SQL к базе данных PostgreSQL), мы видим следующее примечание (курсив мой):

Множественные запросы отправлены в один вызов PQexec обрабатывается в одной транзакции, если в строке запроса не указаны явные команды BEGIN/COMMIT, чтобы разделить его на несколько транзакций. Обратите внимание, что возвращенная структура PGresult описывает только результат последней команды, выполняемой из строки.

Так, к сожалению, то, что вы пытаетесь сделать, это просто не поддерживается psycopg2 и libpq. (Это не означает, что другие клиентские интерфейсы для PostgreSQL его не поддерживают, но это выходит за рамки этого вопроса.)

Итак, чтобы ответить на ваш вопрос, что вы делаете неправильно, выполняется несколько SQL-запросы в одном execute() вызывают и пытаются получить все своих результатов после этого, когда на самом деле это невозможно. Вам необходимо явно выполнить каждый запрос и получить результаты по отдельности, либо попытаться найти другой API для PostgreSQL, который поддерживает сразу несколько возвратных наборов результатов.


Питон API Database 2.0 спецификации действительно позволяет для дополнительного nextset() метода, который будет реализован в библиотеке, которая перемещает cursor к следующему результату набору, возвращаемый из выполненных запросов, но этот метод не реализован в psycopg2 (по понятным причинам) и фактически вызывает исключение NotSupportedError, если вы попытаетесь его назвать (см. документы).

Смежные вопросы