diff options
| author | Federico Caselli <cfederico87@gmail.com> | 2022-10-17 22:02:13 +0200 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2022-11-02 21:38:31 -0400 |
| commit | d10b62f54e6b9dd0613c0412b924c1b346ec1611 (patch) | |
| tree | 07d246255d0372c5a7839e1aec354edacf687fdf /lib/sqlalchemy/engine | |
| parent | 66e591cf8a5de6d5dabdecf2bb279dec90962e15 (diff) | |
| download | sqlalchemy-d10b62f54e6b9dd0613c0412b924c1b346ec1611.tar.gz | |
Improve typings of execution options
Fixes: #8605
Change-Id: I4aec83b9f321462427c3f4ac941c3b272255c088
Diffstat (limited to 'lib/sqlalchemy/engine')
| -rw-r--r-- | lib/sqlalchemy/engine/base.py | 105 | ||||
| -rw-r--r-- | lib/sqlalchemy/engine/create.py | 4 | ||||
| -rw-r--r-- | lib/sqlalchemy/engine/default.py | 12 | ||||
| -rw-r--r-- | lib/sqlalchemy/engine/interfaces.py | 44 | ||||
| -rw-r--r-- | lib/sqlalchemy/engine/mock.py | 4 |
5 files changed, 111 insertions, 58 deletions
diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py index 8cbc0163c..9dde9a445 100644 --- a/lib/sqlalchemy/engine/base.py +++ b/lib/sqlalchemy/engine/base.py @@ -4,6 +4,9 @@ # # This module is part of SQLAlchemy and is released under # the MIT License: https://www.opensource.org/licenses/mit-license.php +"""Defines :class:`_engine.Connection` and :class:`_engine.Engine`. + +""" from __future__ import annotations import contextlib @@ -16,7 +19,6 @@ from typing import Iterable from typing import Iterator from typing import List from typing import Mapping -from typing import MutableMapping from typing import NoReturn from typing import Optional from typing import overload @@ -25,13 +27,13 @@ from typing import Type from typing import TypeVar from typing import Union -from .interfaces import _IsolationLevel from .interfaces import BindTyping from .interfaces import ConnectionEventsTarget from .interfaces import DBAPICursor from .interfaces import ExceptionContext from .interfaces import ExecuteStyle from .interfaces import ExecutionContext +from .interfaces import IsolationLevel from .util import _distill_params_20 from .util import _distill_raw_params from .util import TransactionalContext @@ -42,8 +44,6 @@ from .. import util from ..sql import compiler from ..sql import util as sql_util -_CompiledCacheType = MutableMapping[Any, "Compiled"] - if typing.TYPE_CHECKING: from . import CursorResult from . import ScalarResult @@ -55,9 +55,10 @@ if typing.TYPE_CHECKING: from .interfaces import _DBAPIAnyExecuteParams from .interfaces import _DBAPISingleExecuteParams from .interfaces import _ExecuteOptions - from .interfaces import _ExecuteOptionsParameter - from .interfaces import _SchemaTranslateMapType + from .interfaces import CompiledCacheType + from .interfaces import CoreExecuteOptionsParameter from .interfaces import Dialect + from .interfaces import SchemaTranslateMapType from .reflection import Inspector # noqa from .url import URL from ..event import dispatcher @@ -77,9 +78,6 @@ if typing.TYPE_CHECKING: from ..sql.schema import SchemaItem from ..sql.selectable import TypedReturnsRows -"""Defines :class:`_engine.Connection` and :class:`_engine.Engine`. - -""" _T = TypeVar("_T", bound=Any) _EMPTY_EXECUTION_OPTS: _ExecuteOptions = util.EMPTY_DICT @@ -206,7 +204,7 @@ class Connection(ConnectionEventsTarget, inspection.Inspectable["Inspector"]): self.engine.logger.debug(message, *arg, **kw) @property - def _schema_translate_map(self) -> Optional[_SchemaTranslateMapType]: + def _schema_translate_map(self) -> Optional[SchemaTranslateMapType]: return self._execution_options.get("schema_translate_map", None) def schema_for_object(self, obj: HasSchemaAttr) -> Optional[str]: @@ -217,7 +215,7 @@ class Connection(ConnectionEventsTarget, inspection.Inspectable["Inspector"]): name = obj.schema schema_translate_map: Optional[ - Mapping[Optional[str], str] + SchemaTranslateMapType ] = self._execution_options.get("schema_translate_map", None) if ( @@ -235,6 +233,27 @@ class Connection(ConnectionEventsTarget, inspection.Inspectable["Inspector"]): def __exit__(self, type_: Any, value: Any, traceback: Any) -> None: self.close() + @overload + def execution_options( + self, + *, + compiled_cache: Optional[CompiledCacheType] = ..., + logging_token: str = ..., + isolation_level: IsolationLevel = ..., + no_parameters: bool = False, + stream_results: bool = False, + max_row_buffer: int = ..., + yield_per: int = ..., + insertmanyvalues_page_size: int = ..., + schema_translate_map: Optional[SchemaTranslateMapType] = ..., + **opt: Any, + ) -> Connection: + ... + + @overload + def execution_options(self, **opt: Any) -> Connection: + ... + def execution_options(self, **opt: Any) -> Connection: r"""Set non-SQL options for the connection which take effect during execution. @@ -440,7 +459,8 @@ class Connection(ConnectionEventsTarget, inspection.Inspectable["Inspector"]): :ref:`orm_queryguide_yield_per` - in the :ref:`queryguide_toplevel` describing the ORM version of ``yield_per`` - :param insertmanyvalues_page_size: number of rows to format into an + :param insertmanyvalues_page_size: Available on: :class:`_engine.Connection`, + :class:`_engine.Engine`. Number of rows to format into an INSERT statement when the statement uses "insertmanyvalues" mode, which is a paged form of bulk insert that is used for many backends when using :term:`executemany` execution typically in conjunction @@ -560,7 +580,7 @@ class Connection(ConnectionEventsTarget, inspection.Inspectable["Inspector"]): else: return self._dbapi_connection - def get_isolation_level(self) -> _IsolationLevel: + def get_isolation_level(self) -> IsolationLevel: """Return the current isolation level assigned to this :class:`_engine.Connection`. @@ -600,7 +620,7 @@ class Connection(ConnectionEventsTarget, inspection.Inspectable["Inspector"]): self._handle_dbapi_exception(e, None, None, None, None) @property - def default_isolation_level(self) -> Optional[_IsolationLevel]: + def default_isolation_level(self) -> Optional[IsolationLevel]: """The default isolation level assigned to this :class:`_engine.Connection`. @@ -1239,7 +1259,7 @@ class Connection(ConnectionEventsTarget, inspection.Inspectable["Inspector"]): statement: TypedReturnsRows[Tuple[_T]], parameters: Optional[_CoreSingleExecuteParams] = None, *, - execution_options: Optional[_ExecuteOptionsParameter] = None, + execution_options: Optional[CoreExecuteOptionsParameter] = None, ) -> Optional[_T]: ... @@ -1249,7 +1269,7 @@ class Connection(ConnectionEventsTarget, inspection.Inspectable["Inspector"]): statement: Executable, parameters: Optional[_CoreSingleExecuteParams] = None, *, - execution_options: Optional[_ExecuteOptionsParameter] = None, + execution_options: Optional[CoreExecuteOptionsParameter] = None, ) -> Any: ... @@ -1258,7 +1278,7 @@ class Connection(ConnectionEventsTarget, inspection.Inspectable["Inspector"]): statement: Executable, parameters: Optional[_CoreSingleExecuteParams] = None, *, - execution_options: Optional[_ExecuteOptionsParameter] = None, + execution_options: Optional[CoreExecuteOptionsParameter] = None, ) -> Any: r"""Executes a SQL statement construct and returns a scalar object. @@ -1288,7 +1308,7 @@ class Connection(ConnectionEventsTarget, inspection.Inspectable["Inspector"]): statement: TypedReturnsRows[Tuple[_T]], parameters: Optional[_CoreSingleExecuteParams] = None, *, - execution_options: Optional[_ExecuteOptionsParameter] = None, + execution_options: Optional[CoreExecuteOptionsParameter] = None, ) -> ScalarResult[_T]: ... @@ -1298,7 +1318,7 @@ class Connection(ConnectionEventsTarget, inspection.Inspectable["Inspector"]): statement: Executable, parameters: Optional[_CoreSingleExecuteParams] = None, *, - execution_options: Optional[_ExecuteOptionsParameter] = None, + execution_options: Optional[CoreExecuteOptionsParameter] = None, ) -> ScalarResult[Any]: ... @@ -1307,7 +1327,7 @@ class Connection(ConnectionEventsTarget, inspection.Inspectable["Inspector"]): statement: Executable, parameters: Optional[_CoreSingleExecuteParams] = None, *, - execution_options: Optional[_ExecuteOptionsParameter] = None, + execution_options: Optional[CoreExecuteOptionsParameter] = None, ) -> ScalarResult[Any]: """Executes and returns a scalar result set, which yields scalar values from the first column of each row. @@ -1333,7 +1353,7 @@ class Connection(ConnectionEventsTarget, inspection.Inspectable["Inspector"]): statement: TypedReturnsRows[_T], parameters: Optional[_CoreAnyExecuteParams] = None, *, - execution_options: Optional[_ExecuteOptionsParameter] = None, + execution_options: Optional[CoreExecuteOptionsParameter] = None, ) -> CursorResult[_T]: ... @@ -1343,7 +1363,7 @@ class Connection(ConnectionEventsTarget, inspection.Inspectable["Inspector"]): statement: Executable, parameters: Optional[_CoreAnyExecuteParams] = None, *, - execution_options: Optional[_ExecuteOptionsParameter] = None, + execution_options: Optional[CoreExecuteOptionsParameter] = None, ) -> CursorResult[Any]: ... @@ -1352,7 +1372,7 @@ class Connection(ConnectionEventsTarget, inspection.Inspectable["Inspector"]): statement: Executable, parameters: Optional[_CoreAnyExecuteParams] = None, *, - execution_options: Optional[_ExecuteOptionsParameter] = None, + execution_options: Optional[CoreExecuteOptionsParameter] = None, ) -> CursorResult[Any]: r"""Executes a SQL statement construct and returns a :class:`_engine.CursorResult`. @@ -1401,7 +1421,7 @@ class Connection(ConnectionEventsTarget, inspection.Inspectable["Inspector"]): self, func: FunctionElement[Any], distilled_parameters: _CoreMultiExecuteParams, - execution_options: _ExecuteOptionsParameter, + execution_options: CoreExecuteOptionsParameter, ) -> CursorResult[Any]: """Execute a sql.FunctionElement object.""" @@ -1413,7 +1433,7 @@ class Connection(ConnectionEventsTarget, inspection.Inspectable["Inspector"]): self, default: DefaultGenerator, distilled_parameters: _CoreMultiExecuteParams, - execution_options: _ExecuteOptionsParameter, + execution_options: CoreExecuteOptionsParameter, ) -> Any: """Execute a schema.ColumnDefault object.""" @@ -1472,7 +1492,7 @@ class Connection(ConnectionEventsTarget, inspection.Inspectable["Inspector"]): self, ddl: ExecutableDDLElement, distilled_parameters: _CoreMultiExecuteParams, - execution_options: _ExecuteOptionsParameter, + execution_options: CoreExecuteOptionsParameter, ) -> CursorResult[Any]: """Execute a schema.DDL object.""" @@ -1569,7 +1589,7 @@ class Connection(ConnectionEventsTarget, inspection.Inspectable["Inspector"]): self, elem: Executable, distilled_parameters: _CoreMultiExecuteParams, - execution_options: _ExecuteOptionsParameter, + execution_options: CoreExecuteOptionsParameter, ) -> CursorResult[Any]: """Execute a sql.ClauseElement object.""" @@ -1603,7 +1623,7 @@ class Connection(ConnectionEventsTarget, inspection.Inspectable["Inspector"]): "schema_translate_map", None ) - compiled_cache: Optional[_CompiledCacheType] = execution_options.get( + compiled_cache: Optional[CompiledCacheType] = execution_options.get( "compiled_cache", self.engine._compiled_cache ) @@ -1642,7 +1662,7 @@ class Connection(ConnectionEventsTarget, inspection.Inspectable["Inspector"]): self, compiled: Compiled, distilled_parameters: _CoreMultiExecuteParams, - execution_options: _ExecuteOptionsParameter = _EMPTY_EXECUTION_OPTS, + execution_options: CoreExecuteOptionsParameter = _EMPTY_EXECUTION_OPTS, ) -> CursorResult[Any]: """Execute a sql.Compiled object. @@ -1692,7 +1712,7 @@ class Connection(ConnectionEventsTarget, inspection.Inspectable["Inspector"]): self, statement: str, parameters: Optional[_DBAPIAnyExecuteParams] = None, - execution_options: Optional[_ExecuteOptionsParameter] = None, + execution_options: Optional[CoreExecuteOptionsParameter] = None, ) -> CursorResult[Any]: r"""Executes a SQL statement construct and returns a :class:`_engine.CursorResult`. @@ -2882,7 +2902,7 @@ class Engine( dispatch: dispatcher[ConnectionEventsTarget] - _compiled_cache: Optional[_CompiledCacheType] + _compiled_cache: Optional[CompiledCacheType] _execution_options: _ExecuteOptions = _EMPTY_EXECUTION_OPTS _has_events: bool = False @@ -2890,7 +2910,7 @@ class Engine( _sqla_logger_namespace: str = "sqlalchemy.engine.Engine" _is_future: bool = False - _schema_translate_map: Optional[_SchemaTranslateMapType] = None + _schema_translate_map: Optional[SchemaTranslateMapType] = None _option_cls: Type[OptionEngine] dialect: Dialect @@ -2980,6 +3000,23 @@ class Engine( self._execution_options = self._execution_options.union(opt) self.dialect.set_engine_execution_options(self, opt) + @overload + def execution_options( + self, + *, + compiled_cache: Optional[CompiledCacheType] = ..., + logging_token: str = ..., + isolation_level: IsolationLevel = ..., + insertmanyvalues_page_size: int = ..., + schema_translate_map: Optional[SchemaTranslateMapType] = ..., + **opt: Any, + ) -> OptionEngine: + ... + + @overload + def execution_options(self, **opt: Any) -> OptionEngine: + ... + def execution_options(self, **opt: Any) -> OptionEngine: """Return a new :class:`_engine.Engine` that will provide :class:`_engine.Connection` objects with the given execution options. @@ -3240,7 +3277,7 @@ class OptionEngineMixin(log.Identified): _sa_propagate_class_events = False dispatch: dispatcher[ConnectionEventsTarget] - _compiled_cache: Optional[_CompiledCacheType] + _compiled_cache: Optional[CompiledCacheType] dialect: Dialect pool: Pool url: URL @@ -3248,7 +3285,7 @@ class OptionEngineMixin(log.Identified): echo: log.echo_property def __init__( - self, proxied: Engine, execution_options: _ExecuteOptionsParameter + self, proxied: Engine, execution_options: CoreExecuteOptionsParameter ): self._proxied = proxied self.url = proxied.url diff --git a/lib/sqlalchemy/engine/create.py b/lib/sqlalchemy/engine/create.py index ef5463972..1ad8c90e7 100644 --- a/lib/sqlalchemy/engine/create.py +++ b/lib/sqlalchemy/engine/create.py @@ -33,8 +33,8 @@ from ..sql import compiler if typing.TYPE_CHECKING: from .base import Engine from .interfaces import _ExecuteOptions - from .interfaces import _IsolationLevel from .interfaces import _ParamStyle + from .interfaces import IsolationLevel from .url import URL from ..log import _EchoFlagType from ..pool import _CreatorFnType @@ -59,7 +59,7 @@ def create_engine( hide_parameters: bool = ..., implicit_returning: Literal[True] = ..., insertmanyvalues_page_size: int = ..., - isolation_level: _IsolationLevel = ..., + isolation_level: IsolationLevel = ..., json_deserializer: Callable[..., Any] = ..., json_serializer: Callable[..., Any] = ..., label_length: Optional[int] = ..., diff --git a/lib/sqlalchemy/engine/default.py b/lib/sqlalchemy/engine/default.py index 71ceb3301..e5d613dd5 100644 --- a/lib/sqlalchemy/engine/default.py +++ b/lib/sqlalchemy/engine/default.py @@ -75,10 +75,10 @@ if typing.TYPE_CHECKING: from .interfaces import _DBAPICursorDescription from .interfaces import _DBAPIMultiExecuteParams from .interfaces import _ExecuteOptions - from .interfaces import _IsolationLevel from .interfaces import _MutableCoreSingleExecuteParams from .interfaces import _ParamStyle from .interfaces import DBAPIConnection + from .interfaces import IsolationLevel from .row import Row from .url import URL from ..event import _ListenerFnType @@ -280,7 +280,7 @@ class DefaultDialect(Dialect): def __init__( self, paramstyle: Optional[_ParamStyle] = None, - isolation_level: Optional[_IsolationLevel] = None, + isolation_level: Optional[IsolationLevel] = None, dbapi: Optional[ModuleType] = None, implicit_returning: Literal[True] = True, supports_native_boolean: Optional[bool] = None, @@ -582,13 +582,13 @@ class DefaultDialect(Dialect): return [[], opts] def set_engine_execution_options( - self, engine: Engine, opts: Mapping[str, str] + self, engine: Engine, opts: Mapping[str, Any] ) -> None: supported_names = set(self.connection_characteristics).intersection( opts ) if supported_names: - characteristics: Mapping[str, str] = util.immutabledict( + characteristics: Mapping[str, Any] = util.immutabledict( (name, opts[name]) for name in supported_names ) @@ -599,13 +599,13 @@ class DefaultDialect(Dialect): ) def set_connection_execution_options( - self, connection: Connection, opts: Mapping[str, str] + self, connection: Connection, opts: Mapping[str, Any] ) -> None: supported_names = set(self.connection_characteristics).intersection( opts ) if supported_names: - characteristics: Mapping[str, str] = util.immutabledict( + characteristics: Mapping[str, Any] = util.immutabledict( (name, opts[name]) for name in supported_names ) self._set_connection_characteristics(connection, characteristics) diff --git a/lib/sqlalchemy/engine/interfaces.py b/lib/sqlalchemy/engine/interfaces.py index fb59acbd0..7395b2fa4 100644 --- a/lib/sqlalchemy/engine/interfaces.py +++ b/lib/sqlalchemy/engine/interfaces.py @@ -250,10 +250,8 @@ _AnySingleExecuteParams = _DBAPISingleExecuteParams _AnyMultiExecuteParams = _DBAPIMultiExecuteParams _AnyExecuteParams = _DBAPIAnyExecuteParams - -_ExecuteOptions = immutabledict[str, Any] -_ExecuteOptionsParameter = Mapping[str, Any] -_SchemaTranslateMapType = Mapping[str, str] +CompiledCacheType = MutableMapping[Any, "Compiled"] +SchemaTranslateMapType = Mapping[Optional[str], Optional[str]] _ImmutableExecuteOptions = immutabledict[str, Any] @@ -261,7 +259,7 @@ _ParamStyle = Literal["qmark", "numeric", "named", "format", "pyformat"] _GenericSetInputSizesType = List[Tuple[str, Any, "TypeEngine[Any]"]] -_IsolationLevel = Literal[ +IsolationLevel = Literal[ "SERIALIZABLE", "REPEATABLE READ", "READ COMMITTED", @@ -270,6 +268,24 @@ _IsolationLevel = Literal[ ] +class _CoreKnownExecutionOptions(TypedDict, total=False): + compiled_cache: Optional[CompiledCacheType] + logging_token: str + isolation_level: IsolationLevel + no_parameters: bool + stream_results: bool + max_row_buffer: int + yield_per: int + insertmanyvalues_page_size: int + schema_translate_map: Optional[SchemaTranslateMapType] + + +_ExecuteOptions = immutabledict[str, Any] +CoreExecuteOptionsParameter = Union[ + _CoreKnownExecutionOptions, Mapping[str, Any] +] + + class ReflectedIdentity(TypedDict): """represent the reflected IDENTITY structure of a column, corresponding to the :class:`_schema.Identity` construct. @@ -735,11 +751,11 @@ class Dialect(EventTarget): # NOTE: this does not take into effect engine-level isolation level. # not clear if this should be changed, seems like it should - default_isolation_level: Optional[_IsolationLevel] + default_isolation_level: Optional[IsolationLevel] """the isolation that is implicitly present on new connections""" # create_engine() -> isolation_level currently goes here - _on_connect_isolation_level: Optional[_IsolationLevel] + _on_connect_isolation_level: Optional[IsolationLevel] execution_ctx_cls: Type["ExecutionContext"] """a :class:`.ExecutionContext` class used to handle statement execution""" @@ -2333,7 +2349,7 @@ class Dialect(EventTarget): raise NotImplementedError() def set_isolation_level( - self, dbapi_connection: DBAPIConnection, level: _IsolationLevel + self, dbapi_connection: DBAPIConnection, level: IsolationLevel ) -> None: """Given a DBAPI connection, set its isolation level. @@ -2368,7 +2384,7 @@ class Dialect(EventTarget): def get_isolation_level( self, dbapi_connection: DBAPIConnection - ) -> _IsolationLevel: + ) -> IsolationLevel: """Given a DBAPI connection, return its isolation level. When working with a :class:`_engine.Connection` object, @@ -2403,7 +2419,7 @@ class Dialect(EventTarget): def get_default_isolation_level( self, dbapi_conn: DBAPIConnection - ) -> _IsolationLevel: + ) -> IsolationLevel: """Given a DBAPI connection, return its isolation level, or a default isolation level if one cannot be retrieved. @@ -2425,7 +2441,7 @@ class Dialect(EventTarget): def get_isolation_level_values( self, dbapi_conn: DBAPIConnection - ) -> List[_IsolationLevel]: + ) -> List[IsolationLevel]: """return a sequence of string isolation level names that are accepted by this dialect. @@ -2468,7 +2484,7 @@ class Dialect(EventTarget): raise NotImplementedError() def _assert_and_set_isolation_level( - self, dbapi_conn: DBAPIConnection, level: _IsolationLevel + self, dbapi_conn: DBAPIConnection, level: IsolationLevel ) -> None: raise NotImplementedError() @@ -2571,7 +2587,7 @@ class Dialect(EventTarget): raise NotImplementedError() def set_engine_execution_options( - self, engine: Engine, opt: _ExecuteOptionsParameter + self, engine: Engine, opts: CoreExecuteOptionsParameter ) -> None: """Establish execution options for a given engine. @@ -2585,7 +2601,7 @@ class Dialect(EventTarget): raise NotImplementedError() def set_connection_execution_options( - self, connection: Connection, opt: _ExecuteOptionsParameter + self, connection: Connection, opts: CoreExecuteOptionsParameter ) -> None: """Establish execution options for a given connection. diff --git a/lib/sqlalchemy/engine/mock.py b/lib/sqlalchemy/engine/mock.py index 77dc21d18..cf01c7254 100644 --- a/lib/sqlalchemy/engine/mock.py +++ b/lib/sqlalchemy/engine/mock.py @@ -23,7 +23,7 @@ from .. import util if typing.TYPE_CHECKING: from .base import Engine from .interfaces import _CoreAnyExecuteParams - from .interfaces import _ExecuteOptionsParameter + from .interfaces import CoreExecuteOptionsParameter from .interfaces import Dialect from .url import URL from ..sql.base import Executable @@ -64,7 +64,7 @@ class MockConnection: self, obj: Executable, parameters: Optional[_CoreAnyExecuteParams] = None, - execution_options: Optional[_ExecuteOptionsParameter] = None, + execution_options: Optional[CoreExecuteOptionsParameter] = None, ) -> Any: return self._execute_impl(obj, parameters) |
