summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/engine/events.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqlalchemy/engine/events.py')
-rw-r--r--lib/sqlalchemy/engine/events.py193
1 files changed, 148 insertions, 45 deletions
diff --git a/lib/sqlalchemy/engine/events.py b/lib/sqlalchemy/engine/events.py
index ab462bbe1..0cbf56a6d 100644
--- a/lib/sqlalchemy/engine/events.py
+++ b/lib/sqlalchemy/engine/events.py
@@ -8,14 +8,41 @@
from __future__ import annotations
+import typing
+from typing import Any
+from typing import Dict
+from typing import Optional
+from typing import Tuple
+from typing import Type
+from typing import Union
+
from .base import Engine
from .interfaces import ConnectionEventsTarget
+from .interfaces import DBAPIConnection
+from .interfaces import DBAPICursor
from .interfaces import Dialect
from .. import event
from .. import exc
-
-
-class ConnectionEvents(event.Events):
+from ..util.typing import Literal
+
+if typing.TYPE_CHECKING:
+ from .base import Connection
+ from .interfaces import _CoreAnyExecuteParams
+ from .interfaces import _CoreMultiExecuteParams
+ from .interfaces import _CoreSingleExecuteParams
+ from .interfaces import _DBAPIAnyExecuteParams
+ from .interfaces import _DBAPIMultiExecuteParams
+ from .interfaces import _DBAPISingleExecuteParams
+ from .interfaces import _ExecuteOptions
+ from .interfaces import ExceptionContext
+ from .interfaces import ExecutionContext
+ from .result import Result
+ from ..pool import ConnectionPoolEntry
+ from ..sql import Executable
+ from ..sql.elements import BindParameter
+
+
+class ConnectionEvents(event.Events[ConnectionEventsTarget]):
"""Available events for
:class:`_engine.Connection` and :class:`_engine.Engine`.
@@ -96,7 +123,12 @@ class ConnectionEvents(event.Events):
_dispatch_target = ConnectionEventsTarget
@classmethod
- def _listen(cls, event_key, retval=False):
+ def _listen( # type: ignore[override]
+ cls,
+ event_key: event._EventKey[ConnectionEventsTarget],
+ retval: bool = False,
+ **kw: Any,
+ ) -> None:
target, identifier, fn = (
event_key.dispatch_target,
event_key.identifier,
@@ -109,7 +141,7 @@ class ConnectionEvents(event.Events):
if identifier == "before_execute":
orig_fn = fn
- def wrap_before_execute(
+ def wrap_before_execute( # type: ignore
conn, clauseelement, multiparams, params, execution_options
):
orig_fn(
@@ -125,7 +157,7 @@ class ConnectionEvents(event.Events):
elif identifier == "before_cursor_execute":
orig_fn = fn
- def wrap_before_cursor_execute(
+ def wrap_before_cursor_execute( # type: ignore
conn, cursor, statement, parameters, context, executemany
):
orig_fn(
@@ -163,8 +195,15 @@ class ConnectionEvents(event.Events):
),
)
def before_execute(
- self, conn, clauseelement, multiparams, params, execution_options
- ):
+ self,
+ conn: Connection,
+ clauseelement: Executable,
+ multiparams: _CoreMultiExecuteParams,
+ params: _CoreSingleExecuteParams,
+ execution_options: _ExecuteOptions,
+ ) -> Optional[
+ Tuple[Executable, _CoreMultiExecuteParams, _CoreSingleExecuteParams]
+ ]:
"""Intercept high level execute() events, receiving uncompiled
SQL constructs and other objects prior to rendering into SQL.
@@ -214,13 +253,13 @@ class ConnectionEvents(event.Events):
)
def after_execute(
self,
- conn,
- clauseelement,
- multiparams,
- params,
- execution_options,
- result,
- ):
+ conn: Connection,
+ clauseelement: Executable,
+ multiparams: _CoreMultiExecuteParams,
+ params: _CoreSingleExecuteParams,
+ execution_options: _ExecuteOptions,
+ result: Result,
+ ) -> None:
"""Intercept high level execute() events after execute.
@@ -244,8 +283,14 @@ class ConnectionEvents(event.Events):
"""
def before_cursor_execute(
- self, conn, cursor, statement, parameters, context, executemany
- ):
+ self,
+ conn: Connection,
+ cursor: DBAPICursor,
+ statement: str,
+ parameters: _DBAPIAnyExecuteParams,
+ context: Optional[ExecutionContext],
+ executemany: bool,
+ ) -> Optional[Tuple[str, _DBAPIAnyExecuteParams]]:
"""Intercept low-level cursor execute() events before execution,
receiving the string SQL statement and DBAPI-specific parameter list to
be invoked against a cursor.
@@ -286,8 +331,14 @@ class ConnectionEvents(event.Events):
"""
def after_cursor_execute(
- self, conn, cursor, statement, parameters, context, executemany
- ):
+ self,
+ conn: Connection,
+ cursor: DBAPICursor,
+ statement: str,
+ parameters: _DBAPIAnyExecuteParams,
+ context: Optional[ExecutionContext],
+ executemany: bool,
+ ) -> None:
"""Intercept low-level cursor execute() events after execution.
:param conn: :class:`_engine.Connection` object
@@ -305,7 +356,9 @@ class ConnectionEvents(event.Events):
"""
- def handle_error(self, exception_context):
+ def handle_error(
+ self, exception_context: ExceptionContext
+ ) -> Optional[BaseException]:
r"""Intercept all exceptions processed by the
:class:`_engine.Connection`.
@@ -439,7 +492,7 @@ class ConnectionEvents(event.Events):
@event._legacy_signature(
"2.0", ["conn", "branch"], converter=lambda conn: (conn, False)
)
- def engine_connect(self, conn):
+ def engine_connect(self, conn: Connection) -> None:
"""Intercept the creation of a new :class:`_engine.Connection`.
This event is called typically as the direct result of calling
@@ -475,7 +528,9 @@ class ConnectionEvents(event.Events):
"""
- def set_connection_execution_options(self, conn, opts):
+ def set_connection_execution_options(
+ self, conn: Connection, opts: Dict[str, Any]
+ ) -> None:
"""Intercept when the :meth:`_engine.Connection.execution_options`
method is called.
@@ -494,8 +549,12 @@ class ConnectionEvents(event.Events):
:param opts: dictionary of options that were passed to the
:meth:`_engine.Connection.execution_options` method.
+ This dictionary may be modified in place to affect the ultimate
+ options which take effect.
+
+ .. versionadded:: 2.0 the ``opts`` dictionary may be modified
+ in place.
- .. versionadded:: 0.9.0
.. seealso::
@@ -507,7 +566,9 @@ class ConnectionEvents(event.Events):
"""
- def set_engine_execution_options(self, engine, opts):
+ def set_engine_execution_options(
+ self, engine: Engine, opts: Dict[str, Any]
+ ) -> None:
"""Intercept when the :meth:`_engine.Engine.execution_options`
method is called.
@@ -526,8 +587,11 @@ class ConnectionEvents(event.Events):
:param opts: dictionary of options that were passed to the
:meth:`_engine.Connection.execution_options` method.
+ This dictionary may be modified in place to affect the ultimate
+ options which take effect.
- .. versionadded:: 0.9.0
+ .. versionadded:: 2.0 the ``opts`` dictionary may be modified
+ in place.
.. seealso::
@@ -539,7 +603,7 @@ class ConnectionEvents(event.Events):
"""
- def engine_disposed(self, engine):
+ def engine_disposed(self, engine: Engine) -> None:
"""Intercept when the :meth:`_engine.Engine.dispose` method is called.
The :meth:`_engine.Engine.dispose` method instructs the engine to
@@ -559,14 +623,14 @@ class ConnectionEvents(event.Events):
"""
- def begin(self, conn):
+ def begin(self, conn: Connection) -> None:
"""Intercept begin() events.
:param conn: :class:`_engine.Connection` object
"""
- def rollback(self, conn):
+ def rollback(self, conn: Connection) -> None:
"""Intercept rollback() events, as initiated by a
:class:`.Transaction`.
@@ -584,7 +648,7 @@ class ConnectionEvents(event.Events):
"""
- def commit(self, conn):
+ def commit(self, conn: Connection) -> None:
"""Intercept commit() events, as initiated by a
:class:`.Transaction`.
@@ -596,7 +660,7 @@ class ConnectionEvents(event.Events):
:param conn: :class:`_engine.Connection` object
"""
- def savepoint(self, conn, name):
+ def savepoint(self, conn: Connection, name: str) -> None:
"""Intercept savepoint() events.
:param conn: :class:`_engine.Connection` object
@@ -604,7 +668,9 @@ class ConnectionEvents(event.Events):
"""
- def rollback_savepoint(self, conn, name, context):
+ def rollback_savepoint(
+ self, conn: Connection, name: str, context: None
+ ) -> None:
"""Intercept rollback_savepoint() events.
:param conn: :class:`_engine.Connection` object
@@ -614,7 +680,9 @@ class ConnectionEvents(event.Events):
"""
# TODO: deprecate "context"
- def release_savepoint(self, conn, name, context):
+ def release_savepoint(
+ self, conn: Connection, name: str, context: None
+ ) -> None:
"""Intercept release_savepoint() events.
:param conn: :class:`_engine.Connection` object
@@ -624,7 +692,7 @@ class ConnectionEvents(event.Events):
"""
# TODO: deprecate "context"
- def begin_twophase(self, conn, xid):
+ def begin_twophase(self, conn: Connection, xid: Any) -> None:
"""Intercept begin_twophase() events.
:param conn: :class:`_engine.Connection` object
@@ -632,14 +700,16 @@ class ConnectionEvents(event.Events):
"""
- def prepare_twophase(self, conn, xid):
+ def prepare_twophase(self, conn: Connection, xid: Any) -> None:
"""Intercept prepare_twophase() events.
:param conn: :class:`_engine.Connection` object
:param xid: two-phase XID identifier
"""
- def rollback_twophase(self, conn, xid, is_prepared):
+ def rollback_twophase(
+ self, conn: Connection, xid: Any, is_prepared: bool
+ ) -> None:
"""Intercept rollback_twophase() events.
:param conn: :class:`_engine.Connection` object
@@ -649,7 +719,9 @@ class ConnectionEvents(event.Events):
"""
- def commit_twophase(self, conn, xid, is_prepared):
+ def commit_twophase(
+ self, conn: Connection, xid: Any, is_prepared: bool
+ ) -> None:
"""Intercept commit_twophase() events.
:param conn: :class:`_engine.Connection` object
@@ -660,7 +732,7 @@ class ConnectionEvents(event.Events):
"""
-class DialectEvents(event.Events):
+class DialectEvents(event.Events[Dialect]):
"""event interface for execution-replacement functions.
These events allow direct instrumentation and replacement
@@ -694,14 +766,20 @@ class DialectEvents(event.Events):
_dispatch_target = Dialect
@classmethod
- def _listen(cls, event_key, retval=False):
+ def _listen( # type: ignore
+ cls,
+ event_key: event._EventKey[Dialect],
+ retval: bool = False,
+ ) -> None:
target = event_key.dispatch_target
target._has_events = True
event_key.base_listen()
@classmethod
- def _accept_with(cls, target):
+ def _accept_with(
+ cls, target: Union[Engine, Type[Engine], Dialect, Type[Dialect]]
+ ) -> Union[Dialect, Type[Dialect]]:
if isinstance(target, type):
if issubclass(target, Engine):
return Dialect
@@ -712,7 +790,13 @@ class DialectEvents(event.Events):
else:
return target
- def do_connect(self, dialect, conn_rec, cargs, cparams):
+ def do_connect(
+ self,
+ dialect: Dialect,
+ conn_rec: ConnectionPoolEntry,
+ cargs: Tuple[Any, ...],
+ cparams: Dict[str, Any],
+ ) -> Optional[DBAPIConnection]:
"""Receive connection arguments before a connection is made.
This event is useful in that it allows the handler to manipulate the
@@ -745,7 +829,13 @@ class DialectEvents(event.Events):
"""
- def do_executemany(self, cursor, statement, parameters, context):
+ def do_executemany(
+ self,
+ cursor: DBAPICursor,
+ statement: str,
+ parameters: _DBAPIMultiExecuteParams,
+ context: ExecutionContext,
+ ) -> Optional[Literal[True]]:
"""Receive a cursor to have executemany() called.
Return the value True to halt further events from invoking,
@@ -754,7 +844,9 @@ class DialectEvents(event.Events):
"""
- def do_execute_no_params(self, cursor, statement, context):
+ def do_execute_no_params(
+ self, cursor: DBAPICursor, statement: str, context: ExecutionContext
+ ) -> Optional[Literal[True]]:
"""Receive a cursor to have execute() with no parameters called.
Return the value True to halt further events from invoking,
@@ -763,7 +855,13 @@ class DialectEvents(event.Events):
"""
- def do_execute(self, cursor, statement, parameters, context):
+ def do_execute(
+ self,
+ cursor: DBAPICursor,
+ statement: str,
+ parameters: _DBAPISingleExecuteParams,
+ context: ExecutionContext,
+ ) -> Optional[Literal[True]]:
"""Receive a cursor to have execute() called.
Return the value True to halt further events from invoking,
@@ -773,8 +871,13 @@ class DialectEvents(event.Events):
"""
def do_setinputsizes(
- self, inputsizes, cursor, statement, parameters, context
- ):
+ self,
+ inputsizes: Dict[BindParameter[Any], Any],
+ cursor: DBAPICursor,
+ statement: str,
+ parameters: _DBAPIAnyExecuteParams,
+ context: ExecutionContext,
+ ) -> None:
"""Receive the setinputsizes dictionary for possible modification.
This event is emitted in the case where the dialect makes use of the