SQLAlchemy: @event.listens_for(движок, ‘handle_error’) всегда повторно вызывает ошибку

#mysql #error-handling #sqlalchemy #flask-sqlalchemy

#mysql #обработка ошибок #sqlalchemy #колба-sqlalchemy

Вопрос:

Мне нужно перехватывать такие ошибки, как «база данных не существует» или «таблица не существует». Вот что я пытаюсь сделать:

 from flask_sqlalchemy import SQLAlchemy from sqlalchemy import event from sqlalchemy.engine import Engine   class MultiTenantSQLAlchemy(SQLAlchemy): # type: ignore  def __init__(self, *args, **kwargs):  super().__init__(*args, **kwargs)   @event.listens_for(Engine, 'handle_error')  def receive_handle_error(exception_context):  print("listen for the 'handle_error' event")  print(exception_context)  db = MultiTenantSQLAlchemy(flask_app) db.session.execute('SELECT * FROM `table_that_does_not_exit`').fetchone()  

Выход:

 listen for the 'handle_error' event lt;sqlalchemy.engine.base.ExceptionContextImpl object at 0x1140c5710gt;  

но я все равно получаю это исключение:

 ProgrammingError: (MySQLdb._exceptions.ProgrammingError) (1146, "Table 'somedb.some_fake_table' doesn't exist")  

Как я могу подавить исключение?

Ответ №1:

вы можете использовать try, кроме как и поймать ошибку

 from sqlalchemy import exc from flask_sqlalchemy import SQLAlchemy from sqlalchemy import event from sqlalchemy.engine import Engine   class MultiTenantSQLAlchemy(SQLAlchemy): # type: ignore  def __init__(self, *args, **kwargs):  super().__init__(*args, **kwargs)   @event.listens_for(Engine, 'handle_error')  def receive_handle_error(exception_context):  print("listen for the 'handle_error' event")  print(exception_context)  db = MultiTenantSQLAlchemy(flask_app)  try:  db.session.execute('SELECT * FROM `table_that_does_not_exit`').fetchone() except exc.SQLAlchemyError:  pass # do something intelligent here  

Комментарии:

1. Я не могу этого сделать, потому что мне нужно поймать этот тип ошибок в сотне мест.

2. для всех языков нормально использовать try catch в каждом критическом разделе, это единственный способ поймать ошибку. программисты bas делают большие попытки поймать, но это, как я уже сказал, плохая программа

3. @MikeFurlender Вы можете db.session подклассировать и переопределить execute метод, обернув вызов super().execute() в a try/except .