psycopg2 OperationalError: курсор не существует

Я пытаюсь реализовать курсор на стороне сервера, чтобы «обойти» слабость Django ORM, когда дело доходит до получения огромного количества данных из базы данных. Но я не понимаю, как должен быть определен именованный курсор, поскольку мой текущий код, похоже, не работает должным образом. Я определяю курсор так:

id = 'cursor%s' % uuid4().hex
connection = psycopg2.connect('my connection string here')
cursor = connection.cursor(id, cursor_factory=psycopg2.extras.RealDictCursor)

Курсор, кажется, работает в том смысле, что его можно повторять и возвращать ожидаемые записи в виде словаря Python, но когда я пытаюсь закрыть его (cursor.close()), я получаю исключение:

psycopg2 OperationalError: cursor *the generated cursor id* does not exist

Какого черта ?! Итак, какой объект я использую для извлечения данных из базы данных? Использует ли psycopg2 резервный (безымянный) курсор по умолчанию, поскольку тот, который я определил, не найден в моей базе данных (и если да ... мой большой вопрос: обязательно определить курсор на уровне db перед использованием psycopg2?) Я Сильно запутались, вы можете мне помочь?


person daveoncode    schedule 28.09.2013    source источник
comment
Для всех, кто сталкивается с этим, одна из причин, по которой это может произойти, заключается в том, что вы не выполняли миграции (то есть после удаления изменений коллег), и в результате что-то внутри Django умирает, убивая курсор, но скрываясь под этой ошибкой.   -  person btown    schedule 08.04.2018


Ответы (4)


Из документации psycopg2:

"Именованные курсоры обычно создаются БЕЗ УДЕРЖАНИЯ, что означает, что они живут только до тех пор, пока текущая транзакция. Попытка получить из именованного курсора после фиксации () или создать именованный курсор, когда уровень изоляции транзакции соединения установлен на AUTOCOMMIT, приведет к в виде исключения ".

То есть эти курсоры не нужно явно закрывать.

http://initd.org/psycopg/docs/usage.html#server-side-cursors

person Talvalin    schedule 28.09.2013
comment
Ммм ... Я читал это предложение раньше, но, честно говоря, я не интерпретировал его так, как вы написали ... Я боюсь утечек памяти, и, поскольку существует метод close, я не понимаю, почему я не должен его вызывать. Более того, я сразу называю это тестом, поэтому я должен быть в той же транзакции ... или я ошибаюсь? - person daveoncode; 28.09.2013
comment
Я должен сказать, что не уверен. В качестве теста попробуйте установить для параметра no hold значение True и посмотрите, можно ли закрыть курсор без каких-либо исключений. - person Talvalin; 29.09.2013
comment
После нескольких часов тестов, отладки и чтения я могу сказать, что мне не нужно закрывать курсоры, но я действительно должен не забыть закрыть соединение, которое они используют ... Я создал несколько хороших классов-оберток :) - person daveoncode; 01.10.2013
comment
@daveoncode: Я столкнулся с той же проблемой, теперь мне интересно, действительно ли необходимо закрытие соединения или просто после его фиксации курсор будет правильно закрыт? Из ответа Талвалина я бы сделал вывод о последнем, а из вашего комментария - о первом. заранее спасибо - person leoschet; 05.10.2018

У меня были эти проблемы, когда я экспериментировал с моими моделями и запускал тест с помощью Pytest.

Для меня проблема была решена путем сброса базы данных моего тестового устройства. Я использовал --create-db вот так:

pytest backend/test_projects/partners/test_actions.py --create-db
person Sydney C.    schedule 25.04.2018

У меня была аналогичная проблема, и я нашел решение. Просто отключите курсоры на стороне сервера, как описано здесь: https://docs.djangoproject.com/en/2.2/ref/settings/#disable-server-side-cursors

        'default': {
            ...
            'USER': DB_USER,
            'PASSWORD': DB_PASSWORD,
            'NAME': DB_NAME,
            'DISABLE_SERVER_SIDE_CURSORS': True,
            ...
        },
person Dmitry P.    schedule 12.03.2021

Я сделал действительно простую и глупую ошибку, забыв запустить ./manage.py makemigrations и ./manage.py migrate перед запуском ./manage.py test, что вызвало эту ошибку.

(Я знаю, что это не отвечает на исходный вопрос, но, поскольку это первый результат от Google, я подумал, что внесу свой вклад. Надеюсь, это нормально)

person user-124812948    schedule 31.03.2021
comment
Это решило мою проблему, я забыл выполнить миграцию, и unit tests django rest не показывал никаких связанных ошибок, но основное приложение показало. - person nck; 11.06.2021