Ошибка с использованием PyGreSQL. pg.DatabaseError: последний запрос не вернул кортежи - PullRequest
0 голосов
/ 05 мая 2018

Я использую pgdb (PyGreSQL) в своем проекте для подключения к работающей БД. Я написал генератор для выборки строк с нумерацией страниц из огромных таблиц.

# DbHelper.py

...

def GetMultipleRowsGenerator(self, query, page_size=None):
    """Execute a query and return the generator
    for a fetching rows
    """
    if self._condition:
        self._condition.acquire()
    try:
        self.VerifyConnection()
        return pgsqlUtils.dbGetMultipleRowsGenerator(self._dbConnection, query, page_size)
    finally:
        if self._condition:
            self._condition.release()

...

# pgsqlUtils.py

...

def dbGetMultipleRowsGenerator(db, query, page_size=None):
    if not query.strip().lower().startswith('select '):
        raise ValueError("Bad query '%s'. Query must starts with 'SELECT ...' for a generator." % query)

    if page_size is not None:
        try:
            page_size = int(page_size)
        except TypeError:
            raise ValueError("Expected int type for 'page_size' (%s given)." % page_size)

        if page_size <= 0:
            raise ValueError("The 'page_size' must be greater than 0 (but %s given)." % page_size)

    def get_generator(q):
        c = None
        try:
            c = db.cursor()
        except SyntaxError:
            pass

        try:
            c.execute(q)

            while True:
                r = c.fetchone()
                if r is None:
                    break
                yield r

        except SyntaxError:
            pass
        finally:
            if c is not None:
                c.close()
            db.commit()

    orig_query = query
    page = -1

    while True:
        query = orig_query
        if page_size is not None:
            page += 1
            offset = page * page_size
            query = "%s OFFSET %s LIMIT %s" % (orig_query, offset, page_size)

        generator = get_generator(query)

        row = None
        while True:
            try:
                row = next(generator)
            except StopIteration:
                break

            yield row

        if row is None:
            break  # no rows - end of table

...

с использованием генератора:

curr_data_generator = \
    self.conn.GetMultipleRowsGenerator("SELECT * FROM %s" % temp_tablename, page_size=100000)

while True: 
    try:
        data = next(curr_data_generator)
    except StopIteration:
        break

    # do something with data ...

И это хорошо работает, но иногда я получаю следующее исключение:

   File "pgsqlUtils.py", line 111, in dbGetMultipleRowsGenerator
   File "pgsqlUtils.py", line 84, in get_generator
   File "/usr/myproject/depot/Python-3.4.3/lib/python3.4/site-packages/PyGreSQL-5.0-py3.4-linux-x86_64.egg/pgdb.py", line 958, in fetchone
    res = self.fetchmany(1, False)
   File "/usr/myproject/depot/Python-3.4.3/lib/python3.4/site-packages/PyGreSQL-5.0-py3.4-linux-x86_64.egg/pgdb.py", line 981, in fetchmany
    result = self._src.fetch(size)
 pg.DatabaseError: Last query did not return tuples

Сведения об окружающей среде

  • Python версия: 3.4.3
  • ОС: CentOS релиз 6,6
  • Я использую этот код в многопоточном режиме.

Почему это происходит? И как я могу это исправить?

...