Исключение ResourceClosedError
Исключение ResourceClosedError относится к группе
SQLAlchemyError и сигнализирует о том, что
ресурс (соединение, результат запроса или курсор)
уже был закрыт, а код пытается выполнить над ним
операцию. Чаще всего исключение появляется при
обращении к объекту Result после выхода из
контекстного менеджера with или после
явного вызова метода close. Параметров у
исключения нет - оно наследуется от
SQLAlchemyError и принимает стандартное
сообщение об ошибке.
Синтаксис
from sqlalchemy.exc import ResourceClosedError
raise ResourceClosedError("message")
Пример
Давайте воспроизведем ситуацию, при которой возникает исключение. Откроем соединение через контекстный менеджер, выполним запрос и попробуем прочитать результат уже после закрытия соединения:
from sqlalchemy import create_engine, text
engine = create_engine('sqlite:///:memory:')
with engine.connect() as conn:
res = conn.execute(text('SELECT 1 AS num'))
try:
print(res.fetchall())
except Exception as e:
print(type(e).__name__)
print(e)
Результат выполнения кода:
"ResourceClosedError"
"This result object is closed."
Пример
Давайте перехватим исключение ResourceClosedError
явно через его импорт и обработаем ситуацию корректно:
from sqlalchemy import create_engine, text
from sqlalchemy.exc import ResourceClosedError
engine = create_engine('sqlite:///:memory:')
with engine.connect() as conn:
conn.execute(text('CREATE TABLE articles (id INTEGER, title TEXT)'))
conn.execute(text("INSERT INTO articles (id, title) VALUES (1, 'article')"))
conn.commit()
res = conn.execute(text('SELECT id, title FROM articles'))
try:
rows = res.fetchall()
print(rows)
except ResourceClosedError:
print('Result is already closed, reopen connection')
Результат выполнения кода:
"Result is already closed, reopen connection"
Пример
Давайте покажем корректный подход - читаем результат внутри контекстного менеджера, пока соединение еще открыто:
from sqlalchemy import create_engine, text
engine = create_engine('sqlite:///:memory:')
with engine.connect() as conn:
conn.execute(text('CREATE TABLE articles (id INTEGER, title TEXT)'))
conn.execute(text("INSERT INTO articles (id, title) VALUES (1, 'article')"))
conn.commit()
res = conn.execute(text('SELECT id, title FROM articles'))
for row in res:
print(row)
Результат выполнения кода:
(1, 'article')
Смотрите также
-
класс
SQLAlchemyError,
который является базовым для всех ошибок библиотеки -
класс
InvalidRequestError,
который сигнализирует о некорректном запросе -
класс
DBAPIError,
который оборачивает ошибки драйвера базы данных -
класс
PendingRollbackError,
который возникает при необходимости отката транзакции