From: Mike Bayer Date: Thu, 15 Oct 2020 17:21:34 +0000 (-0400) Subject: indicate legacy ping recipe for handle_error cases X-Git-Tag: rel_1_4_0b1~26 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=41d3e16773e84692b6625ccb67da204b5362d9c3;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git indicate legacy ping recipe for handle_error cases in prep for a new feature as part of #5648. Change-Id: I6720b0ea797c188de5e8163f79fb7b7994d6e76e --- diff --git a/doc/build/core/pooling.rst b/doc/build/core/pooling.rst index a471501a2f..352a752b1a 100644 --- a/doc/build/core/pooling.rst +++ b/doc/build/core/pooling.rst @@ -212,6 +212,8 @@ to three times before giving up, propagating the database error last received. .. versionadded:: 1.2 Added "pre-ping" capability to the :class:`_pool.Pool` class. +.. _pool_disconnects_pessimistic_custom: + Custom / Legacy Pessimistic Ping ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/lib/sqlalchemy/engine/events.py b/lib/sqlalchemy/engine/events.py index bd664fb8fb..9f30a83ce8 100644 --- a/lib/sqlalchemy/engine/events.py +++ b/lib/sqlalchemy/engine/events.py @@ -330,7 +330,7 @@ class ConnectionEvents(event.Events): * exception re-writing * Establishing or disabling whether a connection or the owning connection pool is invalidated or expired in response to a - specific exception. + specific exception [1]_. The hook is called while the cursor from the failed operation (if any) is still open and accessible. Special cleanup operations @@ -340,21 +340,17 @@ class ConnectionEvents(event.Events): the scope of this hook; the rollback of the per-statement transaction also occurs after the hook is called. - For the common case of detecting a "disconnect" situation which - is not currently handled by the SQLAlchemy dialect, the - :attr:`.ExceptionContext.is_disconnect` flag can be set to True which - will cause the exception to be considered as a disconnect situation, - which typically results in the connection pool being invalidated:: + .. note:: - @event.listens_for(Engine, "handle_error") - def handle_exception(context): - if isinstance(context.original_exception, pyodbc.Error): - for code in ( - '08S01', '01002', '08003', - '08007', '08S02', '08001', 'HYT00', 'HY010'): - - if code in str(context.original_exception): - context.is_disconnect = True + .. [1] The pool "pre_ping" handler enabled using the + :paramref:`_sa.create_engine.pool_pre_ping` parameter does + **not** consult this event before deciding if the "ping" + returned false, as opposed to receiving an unhandled error. + For this use case, the :ref:`legacy recipe based on + engine_connect() may be used + `. A future API allow + more comprehensive customization of the "disconnect" + detection mechanism across all functions. A handler function has two options for replacing the SQLAlchemy-constructed exception into one that is user @@ -478,24 +474,12 @@ class ConnectionEvents(event.Events): typically to pre-execute a SELECT of a default value for the purposes of an INSERT statement. - .. versionadded:: 0.9.0 - .. seealso:: - :ref:`pool_disconnects_pessimistic` - illustrates how to use - :meth:`_events.ConnectionEvents.engine_connect` - to transparently ensure pooled connections are connected to the - database. - :meth:`_events.PoolEvents.checkout` the lower-level pool checkout event for an individual DBAPI connection - :meth:`_events.ConnectionEvents.set_connection_execution_options` - - a copy - of a :class:`_engine.Connection` is also made when the - :meth:`_engine.Connection.execution_options` method is called. - """ def set_connection_execution_options(self, conn, opts): diff --git a/lib/sqlalchemy/engine/interfaces.py b/lib/sqlalchemy/engine/interfaces.py index 27de5aaafa..b7bd3627bd 100644 --- a/lib/sqlalchemy/engine/interfaces.py +++ b/lib/sqlalchemy/engine/interfaces.py @@ -1556,6 +1556,16 @@ class ExceptionContext(object): a connection and pool invalidation can be invoked or prevented by changing this flag. + + .. note:: The pool "pre_ping" handler enabled using the + :paramref:`_sa.create_engine.pool_pre_ping` parameter does **not** + consult this event before deciding if the "ping" returned false, + as opposed to receiving an unhandled error. For this use case, the + :ref:`legacy recipe based on engine_connect() may be used + `. A future API allow more + comprehensive customization of the "disconnect" detection mechanism + across all functions. + """ invalidate_pool_on_disconnect = True