psycopg2 именованный курсор удерживается = True - PullRequest
0 голосов
/ 05 октября 2019

Я использую именованный курсор для извлечения 200K + строк и использую атрибут 'withhold = True', таким образом я могу выполнять итерацию, выбирая много (50K) за раз - но мой курсор не сохраняется ...

Вот ошибка / трассировка стека

Traceback (most recent call last):
  File "/home/me/code/etl/etl.py", line 179, in main
    _pg_data = _fetch(_some)
psycopg2.ProgrammingError: named cursor isn't valid anymore

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/me/code/etl/etl.py", line 330, in <module>
    main()
  File "/home/me/code/etl/etl.py", line 271, in main
    logging.error(Fore.LIGHTRED_EX + e + Fore.RESET, exc_info=True)
TypeError: must be str, not ProgrammingError

Вот мой код

from colorama import Fore
from datetime import datetime
import argparse, logging, psycopg2, pyodbc, sys, time, yaml
import _classes.Utils as cpu

def main():
    _cfg_path = "/home/me/code/etl/db.yml"

    with open(_cfg_path, 'r') as _ymlfile:
        _cfg = yaml.load(_ymlfile, Loader=yaml.CLoader)

    # create a connection to the database
        _conn = psycopg2.connect("host={0} dbname={1} user={2} password={3} port={4}".format(_cfg['local_postgres']['host'], _cfg['local_postgres']['db'],
                                                                                          _cfg['local_postgres']['user'], _cfg['local_postgres']['passwd'],
                                                                                             _cfg['local_postgres']['port']))

    _curs_pgsql = _conn.cursor()
    _curs_pgsql.callproc('usp_outbound', ['curs'])
    _curs2_pgsql = _conn.cursor('curs', withhold=True)

    _push_date = datetime.now().strftime("%Y-%m-%d")

    _some = 50000
    _fetch = _curs2_pgsql.fetchmany
    while True:
        _pg_data = _fetch(_some)
        if not _pg_data:
            break
        for _row in _pg_data:
            _params = ()
            _sql = "INSERT INTO dbo.tbl VALUES (?, ?, ?)"
            _params = (_row[0], _row[1], _row[2])
            # ...insert into destination database

            # ...now update source database and set the push and push date flags
            _curs_pgsql.execute("UPDATE products SET pushed = TRUE, pushed_date = (%s) WHERE id = (%s)", (_push_date, _row[2],))
            _conn.commit()

    if _conn:
        # close cursor / close the communication with the PostgreSQL database server
        _curs2_pgsql.close()
        _curs_pgsql.close()
        _conn.close()

Я явно что-то упустил с указанным курсором и как он должен быть определен. ..

В соответствии с документацией -

Задайте значение перед вызовом execute () или используйте параметр удержания connection.cursor (), в противном случае значение не будет иметь эффекта.

... ... ...

Попытка извлечь из именованного курсора после commit () или создать именованный курсор, когда соединение находится в автокоммитережим приведет к исключению. Можно создать курсор WITH HOLD, указав значение True для параметра удержания для курсора () или установив для атрибута удержания значение True перед вызовом execute () для курсора.

Что такоеЯ пропал?

...