1# engine/interfaces.py 
    2# Copyright (C) 2005-2025 the SQLAlchemy authors and contributors 
    3# <see AUTHORS file> 
    4# 
    5# This module is part of SQLAlchemy and is released under 
    6# the MIT License: https://www.opensource.org/licenses/mit-license.php 
    7 
    8"""Define core interfaces used by the engine system.""" 
    9 
    10from __future__ import annotations 
    11 
    12from enum import Enum 
    13from typing import Any 
    14from typing import Awaitable 
    15from typing import Callable 
    16from typing import ClassVar 
    17from typing import Collection 
    18from typing import Dict 
    19from typing import Iterable 
    20from typing import Iterator 
    21from typing import List 
    22from typing import Literal 
    23from typing import Mapping 
    24from typing import MutableMapping 
    25from typing import Optional 
    26from typing import Protocol 
    27from typing import Sequence 
    28from typing import Set 
    29from typing import Tuple 
    30from typing import Type 
    31from typing import TYPE_CHECKING 
    32from typing import TypedDict 
    33from typing import TypeVar 
    34from typing import Union 
    35 
    36from .. import util 
    37from ..event import EventTarget 
    38from ..pool import Pool 
    39from ..pool import PoolProxiedConnection as PoolProxiedConnection 
    40from ..sql.compiler import Compiled as Compiled 
    41from ..sql.compiler import Compiled  # noqa 
    42from ..sql.compiler import TypeCompiler as TypeCompiler 
    43from ..sql.compiler import TypeCompiler  # noqa 
    44from ..util import immutabledict 
    45from ..util.concurrency import await_ 
    46from ..util.typing import NotRequired 
    47 
    48if TYPE_CHECKING: 
    49    from .base import Connection 
    50    from .base import Engine 
    51    from .cursor import CursorResult 
    52    from .url import URL 
    53    from ..connectors.asyncio import AsyncIODBAPIConnection 
    54    from ..event import _ListenerFnType 
    55    from ..event import dispatcher 
    56    from ..exc import StatementError 
    57    from ..sql import Executable 
    58    from ..sql.compiler import _InsertManyValuesBatch 
    59    from ..sql.compiler import AggregateOrderByStyle 
    60    from ..sql.compiler import DDLCompiler 
    61    from ..sql.compiler import IdentifierPreparer 
    62    from ..sql.compiler import InsertmanyvaluesSentinelOpts 
    63    from ..sql.compiler import Linting 
    64    from ..sql.compiler import SQLCompiler 
    65    from ..sql.elements import BindParameter 
    66    from ..sql.elements import ClauseElement 
    67    from ..sql.schema import Column 
    68    from ..sql.schema import DefaultGenerator 
    69    from ..sql.schema import SchemaItem 
    70    from ..sql.schema import Sequence as Sequence_SchemaItem 
    71    from ..sql.sqltypes import Integer 
    72    from ..sql.type_api import _TypeMemoDict 
    73    from ..sql.type_api import TypeEngine 
    74    from ..util.langhelpers import generic_fn_descriptor 
    75 
    76ConnectArgsType = Tuple[Sequence[str], MutableMapping[str, Any]] 
    77 
    78_T = TypeVar("_T", bound="Any") 
    79 
    80 
    81class CacheStats(Enum): 
    82    CACHE_HIT = 0 
    83    CACHE_MISS = 1 
    84    CACHING_DISABLED = 2 
    85    NO_CACHE_KEY = 3 
    86    NO_DIALECT_SUPPORT = 4 
    87 
    88 
    89class ExecuteStyle(Enum): 
    90    """indicates the :term:`DBAPI` cursor method that will be used to invoke 
    91    a statement.""" 
    92 
    93    EXECUTE = 0 
    94    """indicates cursor.execute() will be used""" 
    95 
    96    EXECUTEMANY = 1 
    97    """indicates cursor.executemany() will be used.""" 
    98 
    99    INSERTMANYVALUES = 2 
    100    """indicates cursor.execute() will be used with an INSERT where the 
    101    VALUES expression will be expanded to accommodate for multiple 
    102    parameter sets 
    103 
    104    .. seealso:: 
    105 
    106        :ref:`engine_insertmanyvalues` 
    107 
    108    """ 
    109 
    110 
    111class DBAPIModule(Protocol): 
    112    class Error(Exception): 
    113        def __getattr__(self, key: str) -> Any: ... 
    114 
    115    class OperationalError(Error): 
    116        pass 
    117 
    118    class InterfaceError(Error): 
    119        pass 
    120 
    121    class IntegrityError(Error): 
    122        pass 
    123 
    124    def __getattr__(self, key: str) -> Any: ... 
    125 
    126 
    127class DBAPIConnection(Protocol): 
    128    """protocol representing a :pep:`249` database connection. 
    129 
    130    .. versionadded:: 2.0 
    131 
    132    .. seealso:: 
    133 
    134        `Connection Objects <https://www.python.org/dev/peps/pep-0249/#connection-objects>`_ 
    135        - in :pep:`249` 
    136 
    137    """  # noqa: E501 
    138 
    139    def close(self) -> None: ... 
    140 
    141    def commit(self) -> None: ... 
    142 
    143    def cursor(self, *args: Any, **kwargs: Any) -> DBAPICursor: ... 
    144 
    145    def rollback(self) -> None: ... 
    146 
    147    def __getattr__(self, key: str) -> Any: ... 
    148 
    149    def __setattr__(self, key: str, value: Any) -> None: ... 
    150 
    151 
    152class DBAPIType(Protocol): 
    153    """protocol representing a :pep:`249` database type. 
    154 
    155    .. versionadded:: 2.0 
    156 
    157    .. seealso:: 
    158 
    159        `Type Objects <https://www.python.org/dev/peps/pep-0249/#type-objects>`_ 
    160        - in :pep:`249` 
    161 
    162    """  # noqa: E501 
    163 
    164 
    165class DBAPICursor(Protocol): 
    166    """protocol representing a :pep:`249` database cursor. 
    167 
    168    .. versionadded:: 2.0 
    169 
    170    .. seealso:: 
    171 
    172        `Cursor Objects <https://www.python.org/dev/peps/pep-0249/#cursor-objects>`_ 
    173        - in :pep:`249` 
    174 
    175    """  # noqa: E501 
    176 
    177    @property 
    178    def description( 
    179        self, 
    180    ) -> _DBAPICursorDescription: 
    181        """The description attribute of the Cursor. 
    182 
    183        .. seealso:: 
    184 
    185            `cursor.description <https://www.python.org/dev/peps/pep-0249/#description>`_ 
    186            - in :pep:`249` 
    187 
    188 
    189        """  # noqa: E501 
    190        ... 
    191 
    192    @property 
    193    def rowcount(self) -> int: ... 
    194 
    195    arraysize: int 
    196 
    197    lastrowid: int 
    198 
    199    def close(self) -> None: ... 
    200 
    201    def execute( 
    202        self, 
    203        operation: Any, 
    204        parameters: Optional[_DBAPISingleExecuteParams] = None, 
    205    ) -> Any: ... 
    206 
    207    def executemany( 
    208        self, 
    209        operation: Any, 
    210        parameters: _DBAPIMultiExecuteParams, 
    211    ) -> Any: ... 
    212 
    213    def fetchone(self) -> Optional[Any]: ... 
    214 
    215    def fetchmany(self, size: int = ...) -> Sequence[Any]: ... 
    216 
    217    def fetchall(self) -> Sequence[Any]: ... 
    218 
    219    def setinputsizes(self, sizes: Sequence[Any]) -> None: ... 
    220 
    221    def setoutputsize(self, size: Any, column: Any) -> None: ... 
    222 
    223    def callproc( 
    224        self, procname: str, parameters: Sequence[Any] = ... 
    225    ) -> Any: ... 
    226 
    227    def nextset(self) -> Optional[bool]: ... 
    228 
    229    def __getattr__(self, key: str) -> Any: ... 
    230 
    231 
    232_CoreSingleExecuteParams = Mapping[str, Any] 
    233_MutableCoreSingleExecuteParams = MutableMapping[str, Any] 
    234_CoreMultiExecuteParams = Sequence[_CoreSingleExecuteParams] 
    235_CoreAnyExecuteParams = Union[ 
    236    _CoreMultiExecuteParams, _CoreSingleExecuteParams 
    237] 
    238 
    239_DBAPISingleExecuteParams = Union[Sequence[Any], _CoreSingleExecuteParams] 
    240 
    241_DBAPIMultiExecuteParams = Union[ 
    242    Sequence[Sequence[Any]], _CoreMultiExecuteParams 
    243] 
    244_DBAPIAnyExecuteParams = Union[ 
    245    _DBAPIMultiExecuteParams, _DBAPISingleExecuteParams 
    246] 
    247_DBAPICursorDescription = Sequence[ 
    248    Tuple[ 
    249        str, 
    250        "DBAPIType", 
    251        Optional[int], 
    252        Optional[int], 
    253        Optional[int], 
    254        Optional[int], 
    255        Optional[bool], 
    256    ] 
    257] 
    258 
    259_AnySingleExecuteParams = _DBAPISingleExecuteParams 
    260_AnyMultiExecuteParams = _DBAPIMultiExecuteParams 
    261_AnyExecuteParams = _DBAPIAnyExecuteParams 
    262 
    263CompiledCacheType = MutableMapping[Any, "Compiled"] 
    264SchemaTranslateMapType = Mapping[Optional[str], Optional[str]] 
    265 
    266_ImmutableExecuteOptions = immutabledict[str, Any] 
    267 
    268_ParamStyle = Literal[ 
    269    "qmark", "numeric", "named", "format", "pyformat", "numeric_dollar" 
    270] 
    271 
    272_GenericSetInputSizesType = List[Tuple[str, Any, "TypeEngine[Any]"]] 
    273 
    274IsolationLevel = Literal[ 
    275    "SERIALIZABLE", 
    276    "REPEATABLE READ", 
    277    "READ COMMITTED", 
    278    "READ UNCOMMITTED", 
    279    "AUTOCOMMIT", 
    280] 
    281 
    282 
    283class _CoreKnownExecutionOptions(TypedDict, total=False): 
    284    compiled_cache: Optional[CompiledCacheType] 
    285    logging_token: str 
    286    isolation_level: IsolationLevel 
    287    no_parameters: bool 
    288    stream_results: bool 
    289    max_row_buffer: int 
    290    yield_per: int 
    291    insertmanyvalues_page_size: int 
    292    schema_translate_map: Optional[SchemaTranslateMapType] 
    293    preserve_rowcount: bool 
    294    driver_column_names: bool 
    295 
    296 
    297_ExecuteOptions = immutabledict[str, Any] 
    298CoreExecuteOptionsParameter = Union[ 
    299    _CoreKnownExecutionOptions, Mapping[str, Any] 
    300] 
    301 
    302 
    303class ReflectedIdentity(TypedDict): 
    304    """represent the reflected IDENTITY structure of a column, corresponding 
    305    to the :class:`_schema.Identity` construct. 
    306 
    307    The :class:`.ReflectedIdentity` structure is part of the 
    308    :class:`.ReflectedColumn` structure, which is returned by the 
    309    :meth:`.Inspector.get_columns` method. 
    310 
    311    """ 
    312 
    313    always: bool 
    314    """type of identity column""" 
    315 
    316    on_null: bool 
    317    """indicates ON NULL""" 
    318 
    319    start: int 
    320    """starting index of the sequence""" 
    321 
    322    increment: int 
    323    """increment value of the sequence""" 
    324 
    325    minvalue: int 
    326    """the minimum value of the sequence.""" 
    327 
    328    maxvalue: int 
    329    """the maximum value of the sequence.""" 
    330 
    331    nominvalue: bool 
    332    """no minimum value of the sequence.""" 
    333 
    334    nomaxvalue: bool 
    335    """no maximum value of the sequence.""" 
    336 
    337    cycle: bool 
    338    """allows the sequence to wrap around when the maxvalue 
    339    or minvalue has been reached.""" 
    340 
    341    cache: Optional[int] 
    342    """number of future values in the 
    343    sequence which are calculated in advance.""" 
    344 
    345    order: bool 
    346    """if true, renders the ORDER keyword.""" 
    347 
    348 
    349class ReflectedComputed(TypedDict): 
    350    """Represent the reflected elements of a computed column, corresponding 
    351    to the :class:`_schema.Computed` construct. 
    352 
    353    The :class:`.ReflectedComputed` structure is part of the 
    354    :class:`.ReflectedColumn` structure, which is returned by the 
    355    :meth:`.Inspector.get_columns` method. 
    356 
    357    """ 
    358 
    359    sqltext: str 
    360    """the expression used to generate this column returned 
    361    as a string SQL expression""" 
    362 
    363    persisted: NotRequired[bool] 
    364    """indicates if the value is stored in the table or computed on demand""" 
    365 
    366 
    367class ReflectedColumn(TypedDict): 
    368    """Dictionary representing the reflected elements corresponding to 
    369    a :class:`_schema.Column` object. 
    370 
    371    The :class:`.ReflectedColumn` structure is returned by the 
    372    :class:`.Inspector.get_columns` method. 
    373 
    374    """ 
    375 
    376    name: str 
    377    """column name""" 
    378 
    379    type: TypeEngine[Any] 
    380    """column type represented as a :class:`.TypeEngine` instance.""" 
    381 
    382    nullable: bool 
    383    """boolean flag if the column is NULL or NOT NULL""" 
    384 
    385    default: Optional[str] 
    386    """column default expression as a SQL string""" 
    387 
    388    autoincrement: NotRequired[bool] 
    389    """database-dependent autoincrement flag. 
    390 
    391    This flag indicates if the column has a database-side "autoincrement" 
    392    flag of some kind.   Within SQLAlchemy, other kinds of columns may 
    393    also act as an "autoincrement" column without necessarily having 
    394    such a flag on them. 
    395 
    396    See :paramref:`_schema.Column.autoincrement` for more background on 
    397    "autoincrement". 
    398 
    399    """ 
    400 
    401    comment: NotRequired[Optional[str]] 
    402    """comment for the column, if present. 
    403    Only some dialects return this key 
    404    """ 
    405 
    406    computed: NotRequired[ReflectedComputed] 
    407    """indicates that this column is computed by the database. 
    408    Only some dialects return this key. 
    409    """ 
    410 
    411    identity: NotRequired[ReflectedIdentity] 
    412    """indicates this column is an IDENTITY column. 
    413    Only some dialects return this key. 
    414 
    415    .. versionadded:: 1.4 - added support for identity column reflection. 
    416    """ 
    417 
    418    dialect_options: NotRequired[Dict[str, Any]] 
    419    """Additional dialect-specific options detected for this reflected 
    420    object""" 
    421 
    422 
    423class ReflectedConstraint(TypedDict): 
    424    """Dictionary representing the reflected elements corresponding to 
    425    :class:`.Constraint` 
    426 
    427    A base class for all constraints 
    428    """ 
    429 
    430    name: Optional[str] 
    431    """constraint name""" 
    432 
    433    comment: NotRequired[Optional[str]] 
    434    """comment for the constraint, if present""" 
    435 
    436 
    437class ReflectedCheckConstraint(ReflectedConstraint): 
    438    """Dictionary representing the reflected elements corresponding to 
    439    :class:`.CheckConstraint`. 
    440 
    441    The :class:`.ReflectedCheckConstraint` structure is returned by the 
    442    :meth:`.Inspector.get_check_constraints` method. 
    443 
    444    """ 
    445 
    446    sqltext: str 
    447    """the check constraint's SQL expression""" 
    448 
    449    dialect_options: NotRequired[Dict[str, Any]] 
    450    """Additional dialect-specific options detected for this check constraint 
    451    """ 
    452 
    453 
    454class ReflectedUniqueConstraint(ReflectedConstraint): 
    455    """Dictionary representing the reflected elements corresponding to 
    456    :class:`.UniqueConstraint`. 
    457 
    458    The :class:`.ReflectedUniqueConstraint` structure is returned by the 
    459    :meth:`.Inspector.get_unique_constraints` method. 
    460 
    461    """ 
    462 
    463    column_names: List[str] 
    464    """column names which comprise the unique constraint""" 
    465 
    466    duplicates_index: NotRequired[Optional[str]] 
    467    "Indicates if this unique constraint duplicates an index with this name" 
    468 
    469    dialect_options: NotRequired[Dict[str, Any]] 
    470    """Additional dialect-specific options detected for this unique 
    471    constraint""" 
    472 
    473 
    474class ReflectedPrimaryKeyConstraint(ReflectedConstraint): 
    475    """Dictionary representing the reflected elements corresponding to 
    476    :class:`.PrimaryKeyConstraint`. 
    477 
    478    The :class:`.ReflectedPrimaryKeyConstraint` structure is returned by the 
    479    :meth:`.Inspector.get_pk_constraint` method. 
    480 
    481    """ 
    482 
    483    constrained_columns: List[str] 
    484    """column names which comprise the primary key""" 
    485 
    486    dialect_options: NotRequired[Dict[str, Any]] 
    487    """Additional dialect-specific options detected for this primary key""" 
    488 
    489 
    490class ReflectedForeignKeyConstraint(ReflectedConstraint): 
    491    """Dictionary representing the reflected elements corresponding to 
    492    :class:`.ForeignKeyConstraint`. 
    493 
    494    The :class:`.ReflectedForeignKeyConstraint` structure is returned by 
    495    the :meth:`.Inspector.get_foreign_keys` method. 
    496 
    497    """ 
    498 
    499    constrained_columns: List[str] 
    500    """local column names which comprise the foreign key""" 
    501 
    502    referred_schema: Optional[str] 
    503    """schema name of the table being referred""" 
    504 
    505    referred_table: str 
    506    """name of the table being referred""" 
    507 
    508    referred_columns: List[str] 
    509    """referred column names that correspond to ``constrained_columns``""" 
    510 
    511    options: NotRequired[Dict[str, Any]] 
    512    """Additional options detected for this foreign key constraint""" 
    513 
    514 
    515class ReflectedIndex(TypedDict): 
    516    """Dictionary representing the reflected elements corresponding to 
    517    :class:`.Index`. 
    518 
    519    The :class:`.ReflectedIndex` structure is returned by the 
    520    :meth:`.Inspector.get_indexes` method. 
    521 
    522    """ 
    523 
    524    name: Optional[str] 
    525    """index name""" 
    526 
    527    column_names: List[Optional[str]] 
    528    """column names which the index references. 
    529    An element of this list is ``None`` if it's an expression and is 
    530    returned in the ``expressions`` list. 
    531    """ 
    532 
    533    expressions: NotRequired[List[str]] 
    534    """Expressions that compose the index. This list, when present, contains 
    535    both plain column names (that are also in ``column_names``) and 
    536    expressions (that are ``None`` in ``column_names``). 
    537    """ 
    538 
    539    unique: bool 
    540    """whether or not the index has a unique flag""" 
    541 
    542    duplicates_constraint: NotRequired[Optional[str]] 
    543    "Indicates if this index mirrors a constraint with this name" 
    544 
    545    include_columns: NotRequired[List[str]] 
    546    """columns to include in the INCLUDE clause for supporting databases. 
    547 
    548    .. deprecated:: 2.0 
    549 
    550        Legacy value, will be replaced with 
    551        ``index_dict["dialect_options"]["<dialect name>_include"]`` 
    552 
    553    """ 
    554 
    555    column_sorting: NotRequired[Dict[str, Tuple[str]]] 
    556    """optional dict mapping column names or expressions to tuple of sort 
    557    keywords, which may include ``asc``, ``desc``, ``nulls_first``, 
    558    ``nulls_last``. 
    559    """ 
    560 
    561    dialect_options: NotRequired[Dict[str, Any]] 
    562    """Additional dialect-specific options detected for this index""" 
    563 
    564 
    565class ReflectedTableComment(TypedDict): 
    566    """Dictionary representing the reflected comment corresponding to 
    567    the :attr:`_schema.Table.comment` attribute. 
    568 
    569    The :class:`.ReflectedTableComment` structure is returned by the 
    570    :meth:`.Inspector.get_table_comment` method. 
    571 
    572    """ 
    573 
    574    text: Optional[str] 
    575    """text of the comment""" 
    576 
    577 
    578class BindTyping(Enum): 
    579    """Define different methods of passing typing information for 
    580    bound parameters in a statement to the database driver. 
    581 
    582    .. versionadded:: 2.0 
    583 
    584    """ 
    585 
    586    NONE = 1 
    587    """No steps are taken to pass typing information to the database driver. 
    588 
    589    This is the default behavior for databases such as SQLite, MySQL / MariaDB, 
    590    SQL Server. 
    591 
    592    """ 
    593 
    594    SETINPUTSIZES = 2 
    595    """Use the pep-249 setinputsizes method. 
    596 
    597    This is only implemented for DBAPIs that support this method and for which 
    598    the SQLAlchemy dialect has the appropriate infrastructure for that dialect 
    599    set up.  Current dialects include python-oracledb, cx_Oracle as well as 
    600    optional support for SQL Server using pyodbc. 
    601 
    602    When using setinputsizes, dialects also have a means of only using the 
    603    method for certain datatypes using include/exclude lists. 
    604 
    605    When SETINPUTSIZES is used, the :meth:`.Dialect.do_set_input_sizes` method 
    606    is called for each statement executed which has bound parameters. 
    607 
    608    """ 
    609 
    610    RENDER_CASTS = 3 
    611    """Render casts or other directives in the SQL string. 
    612 
    613    This method is used for all PostgreSQL dialects, including asyncpg, 
    614    pg8000, psycopg, psycopg2.   Dialects which implement this can choose 
    615    which kinds of datatypes are explicitly cast in SQL statements and which 
    616    aren't. 
    617 
    618    When RENDER_CASTS is used, the compiler will invoke the 
    619    :meth:`.SQLCompiler.render_bind_cast` method for the rendered 
    620    string representation of each :class:`.BindParameter` object whose 
    621    dialect-level type sets the :attr:`.TypeEngine.render_bind_cast` attribute. 
    622 
    623    The :meth:`.SQLCompiler.render_bind_cast` is also used to render casts 
    624    for one form of "insertmanyvalues" query, when both 
    625    :attr:`.InsertmanyvaluesSentinelOpts.USE_INSERT_FROM_SELECT` and 
    626    :attr:`.InsertmanyvaluesSentinelOpts.RENDER_SELECT_COL_CASTS` are set, 
    627    where the casts are applied to the intermediary columns e.g. 
    628    "INSERT INTO t (a, b, c) SELECT p0::TYP, p1::TYP, p2::TYP " 
    629    "FROM (VALUES (?, ?), (?, ?), ...)". 
    630 
    631    .. versionadded:: 2.0.10 - :meth:`.SQLCompiler.render_bind_cast` is now 
    632       used within some elements of the "insertmanyvalues" implementation. 
    633 
    634 
    635    """ 
    636 
    637 
    638VersionInfoType = Tuple[Union[int, str], ...] 
    639TableKey = Tuple[Optional[str], str] 
    640 
    641 
    642class Dialect(EventTarget): 
    643    """Define the behavior of a specific database and DB-API combination. 
    644 
    645    Any aspect of metadata definition, SQL query generation, 
    646    execution, result-set handling, or anything else which varies 
    647    between databases is defined under the general category of the 
    648    Dialect.  The Dialect acts as a factory for other 
    649    database-specific object implementations including 
    650    ExecutionContext, Compiled, DefaultGenerator, and TypeEngine. 
    651 
    652    .. note:: Third party dialects should not subclass :class:`.Dialect` 
    653       directly.  Instead, subclass :class:`.default.DefaultDialect` or 
    654       descendant class. 
    655 
    656    """ 
    657 
    658    CACHE_HIT = CacheStats.CACHE_HIT 
    659    CACHE_MISS = CacheStats.CACHE_MISS 
    660    CACHING_DISABLED = CacheStats.CACHING_DISABLED 
    661    NO_CACHE_KEY = CacheStats.NO_CACHE_KEY 
    662    NO_DIALECT_SUPPORT = CacheStats.NO_DIALECT_SUPPORT 
    663 
    664    dispatch: dispatcher[Dialect] 
    665 
    666    name: str 
    667    """identifying name for the dialect from a DBAPI-neutral point of view 
    668      (i.e. 'sqlite') 
    669    """ 
    670 
    671    driver: str 
    672    """identifying name for the dialect's DBAPI""" 
    673 
    674    dialect_description: str 
    675 
    676    dbapi: Optional[DBAPIModule] 
    677    """A reference to the DBAPI module object itself. 
    678 
    679    SQLAlchemy dialects import DBAPI modules using the classmethod 
    680    :meth:`.Dialect.import_dbapi`. The rationale is so that any dialect 
    681    module can be imported and used to generate SQL statements without the 
    682    need for the actual DBAPI driver to be installed.  Only when an 
    683    :class:`.Engine` is constructed using :func:`.create_engine` does the 
    684    DBAPI get imported; at that point, the creation process will assign 
    685    the DBAPI module to this attribute. 
    686 
    687    Dialects should therefore implement :meth:`.Dialect.import_dbapi` 
    688    which will import the necessary module and return it, and then refer 
    689    to ``self.dbapi`` in dialect code in order to refer to the DBAPI module 
    690    contents. 
    691 
    692    .. versionchanged:: The :attr:`.Dialect.dbapi` attribute is exclusively 
    693       used as the per-:class:`.Dialect`-instance reference to the DBAPI 
    694       module.   The previous not-fully-documented ``.Dialect.dbapi()`` 
    695       classmethod is deprecated and replaced by :meth:`.Dialect.import_dbapi`. 
    696 
    697    """ 
    698 
    699    @util.non_memoized_property 
    700    def loaded_dbapi(self) -> DBAPIModule: 
    701        """same as .dbapi, but is never None; will raise an error if no 
    702        DBAPI was set up. 
    703 
    704        .. versionadded:: 2.0 
    705 
    706        """ 
    707        raise NotImplementedError() 
    708 
    709    positional: bool 
    710    """True if the paramstyle for this Dialect is positional.""" 
    711 
    712    paramstyle: str 
    713    """the paramstyle to be used (some DB-APIs support multiple 
    714      paramstyles). 
    715    """ 
    716 
    717    compiler_linting: Linting 
    718 
    719    statement_compiler: Type[SQLCompiler] 
    720    """a :class:`.Compiled` class used to compile SQL statements""" 
    721 
    722    ddl_compiler: Type[DDLCompiler] 
    723    """a :class:`.Compiled` class used to compile DDL statements""" 
    724 
    725    type_compiler_cls: ClassVar[Type[TypeCompiler]] 
    726    """a :class:`.Compiled` class used to compile SQL type objects 
    727 
    728    .. versionadded:: 2.0 
    729 
    730    """ 
    731 
    732    type_compiler_instance: TypeCompiler 
    733    """instance of a :class:`.Compiled` class used to compile SQL type 
    734    objects 
    735 
    736    .. versionadded:: 2.0 
    737 
    738    """ 
    739 
    740    type_compiler: Any 
    741    """legacy; this is a TypeCompiler class at the class level, a 
    742    TypeCompiler instance at the instance level. 
    743 
    744    Refer to type_compiler_instance instead. 
    745 
    746    """ 
    747 
    748    preparer: Type[IdentifierPreparer] 
    749    """a :class:`.IdentifierPreparer` class used to 
    750    quote identifiers. 
    751    """ 
    752 
    753    identifier_preparer: IdentifierPreparer 
    754    """This element will refer to an instance of :class:`.IdentifierPreparer` 
    755    once a :class:`.DefaultDialect` has been constructed. 
    756 
    757    """ 
    758 
    759    server_version_info: Optional[Tuple[Any, ...]] 
    760    """a tuple containing a version number for the DB backend in use. 
    761 
    762    This value is only available for supporting dialects, and is 
    763    typically populated during the initial connection to the database. 
    764    """ 
    765 
    766    default_schema_name: Optional[str] 
    767    """the name of the default schema.  This value is only available for 
    768    supporting dialects, and is typically populated during the 
    769    initial connection to the database. 
    770 
    771    """ 
    772 
    773    # NOTE: this does not take into effect engine-level isolation level. 
    774    # not clear if this should be changed, seems like it should 
    775    default_isolation_level: Optional[IsolationLevel] 
    776    """the isolation that is implicitly present on new connections""" 
    777 
    778    skip_autocommit_rollback: bool 
    779    """Whether or not the :paramref:`.create_engine.skip_autocommit_rollback` 
    780    parameter was set. 
    781 
    782    .. versionadded:: 2.0.43 
    783 
    784    """ 
    785 
    786    # create_engine()  -> isolation_level  currently goes here 
    787    _on_connect_isolation_level: Optional[IsolationLevel] 
    788 
    789    execution_ctx_cls: Type[ExecutionContext] 
    790    """a :class:`.ExecutionContext` class used to handle statement execution""" 
    791 
    792    execute_sequence_format: Union[ 
    793        Type[Tuple[Any, ...]], Type[Tuple[List[Any]]] 
    794    ] 
    795    """either the 'tuple' or 'list' type, depending on what cursor.execute() 
    796    accepts for the second argument (they vary).""" 
    797 
    798    supports_alter: bool 
    799    """``True`` if the database supports ``ALTER TABLE`` - used only for 
    800    generating foreign key constraints in certain circumstances 
    801    """ 
    802 
    803    max_identifier_length: int 
    804    """The maximum length of identifier names.""" 
    805    max_index_name_length: Optional[int] 
    806    """The maximum length of index names if different from 
    807    ``max_identifier_length``.""" 
    808    max_constraint_name_length: Optional[int] 
    809    """The maximum length of constraint names if different from 
    810    ``max_identifier_length``.""" 
    811 
    812    supports_server_side_cursors: Union[generic_fn_descriptor[bool], bool] 
    813    """indicates if the dialect supports server side cursors""" 
    814 
    815    server_side_cursors: bool 
    816    """deprecated; indicates if the dialect should attempt to use server 
    817    side cursors by default""" 
    818 
    819    supports_sane_rowcount: bool 
    820    """Indicate whether the dialect properly implements rowcount for 
    821      ``UPDATE`` and ``DELETE`` statements. 
    822    """ 
    823 
    824    supports_sane_multi_rowcount: bool 
    825    """Indicate whether the dialect properly implements rowcount for 
    826      ``UPDATE`` and ``DELETE`` statements when executed via 
    827      executemany. 
    828    """ 
    829 
    830    supports_empty_insert: bool 
    831    """dialect supports INSERT () VALUES (), i.e. a plain INSERT with no 
    832    columns in it. 
    833 
    834    This is not usually supported; an "empty" insert is typically 
    835    suited using either "INSERT..DEFAULT VALUES" or 
    836    "INSERT ... (col) VALUES (DEFAULT)". 
    837 
    838    """ 
    839 
    840    supports_default_values: bool 
    841    """dialect supports INSERT... DEFAULT VALUES syntax""" 
    842 
    843    supports_default_metavalue: bool 
    844    """dialect supports INSERT...(col) VALUES (DEFAULT) syntax. 
    845 
    846    Most databases support this in some way, e.g. SQLite supports it using 
    847    ``VALUES (NULL)``.    MS SQL Server supports the syntax also however 
    848    is the only included dialect where we have this disabled, as 
    849    MSSQL does not support the field for the IDENTITY column, which is 
    850    usually where we like to make use of the feature. 
    851 
    852    """ 
    853 
    854    default_metavalue_token: str = "DEFAULT" 
    855    """for INSERT... VALUES (DEFAULT) syntax, the token to put in the 
    856    parenthesis. 
    857 
    858    E.g. for SQLite this is the keyword "NULL". 
    859 
    860    """ 
    861 
    862    supports_multivalues_insert: bool 
    863    """Target database supports INSERT...VALUES with multiple value 
    864    sets, i.e. INSERT INTO table (cols) VALUES (...), (...), (...), ... 
    865 
    866    """ 
    867 
    868    aggregate_order_by_style: AggregateOrderByStyle 
    869    """Style of ORDER BY supported for arbitrary aggregate functions 
    870 
    871    .. versionadded:: 2.1 
    872 
    873    """ 
    874 
    875    insert_executemany_returning: bool 
    876    """dialect / driver / database supports some means of providing 
    877    INSERT...RETURNING support when dialect.do_executemany() is used. 
    878 
    879    """ 
    880 
    881    insert_executemany_returning_sort_by_parameter_order: bool 
    882    """dialect / driver / database supports some means of providing 
    883    INSERT...RETURNING support when dialect.do_executemany() is used 
    884    along with the :paramref:`_dml.Insert.returning.sort_by_parameter_order` 
    885    parameter being set. 
    886 
    887    """ 
    888 
    889    update_executemany_returning: bool 
    890    """dialect supports UPDATE..RETURNING with executemany.""" 
    891 
    892    delete_executemany_returning: bool 
    893    """dialect supports DELETE..RETURNING with executemany.""" 
    894 
    895    use_insertmanyvalues: bool 
    896    """if True, indicates "insertmanyvalues" functionality should be used 
    897    to allow for ``insert_executemany_returning`` behavior, if possible. 
    898 
    899    In practice, setting this to True means: 
    900 
    901    if ``supports_multivalues_insert``, ``insert_returning`` and 
    902    ``use_insertmanyvalues`` are all True, the SQL compiler will produce 
    903    an INSERT that will be interpreted by the :class:`.DefaultDialect` 
    904    as an :attr:`.ExecuteStyle.INSERTMANYVALUES` execution that allows 
    905    for INSERT of many rows with RETURNING by rewriting a single-row 
    906    INSERT statement to have multiple VALUES clauses, also executing 
    907    the statement multiple times for a series of batches when large numbers 
    908    of rows are given. 
    909 
    910    The parameter is False for the default dialect, and is set to True for 
    911    SQLAlchemy internal dialects SQLite, MySQL/MariaDB, PostgreSQL, SQL Server. 
    912    It remains at False for Oracle Database, which provides native "executemany 
    913    with RETURNING" support and also does not support 
    914    ``supports_multivalues_insert``.  For MySQL/MariaDB, those MySQL dialects 
    915    that don't support RETURNING will not report 
    916    ``insert_executemany_returning`` as True. 
    917 
    918    .. versionadded:: 2.0 
    919 
    920    .. seealso:: 
    921 
    922        :ref:`engine_insertmanyvalues` 
    923 
    924    """ 
    925 
    926    use_insertmanyvalues_wo_returning: bool 
    927    """if True, and use_insertmanyvalues is also True, INSERT statements 
    928    that don't include RETURNING will also use "insertmanyvalues". 
    929 
    930    .. versionadded:: 2.0 
    931 
    932    .. seealso:: 
    933 
    934        :ref:`engine_insertmanyvalues` 
    935 
    936    """ 
    937 
    938    insertmanyvalues_implicit_sentinel: InsertmanyvaluesSentinelOpts 
    939    """Options indicating the database supports a form of bulk INSERT where 
    940    the autoincrement integer primary key can be reliably used as an ordering 
    941    for INSERTed rows. 
    942 
    943    .. versionadded:: 2.0.10 
    944 
    945    .. seealso:: 
    946 
    947        :ref:`engine_insertmanyvalues_returning_order` 
    948 
    949    """ 
    950 
    951    insertmanyvalues_page_size: int 
    952    """Number of rows to render into an individual INSERT..VALUES() statement 
    953    for :attr:`.ExecuteStyle.INSERTMANYVALUES` executions. 
    954 
    955    The default dialect defaults this to 1000. 
    956 
    957    .. versionadded:: 2.0 
    958 
    959    .. seealso:: 
    960 
    961        :paramref:`_engine.Connection.execution_options.insertmanyvalues_page_size` - 
    962        execution option available on :class:`_engine.Connection`, statements 
    963 
    964    """  # noqa: E501 
    965 
    966    insertmanyvalues_max_parameters: int 
    967    """Alternate to insertmanyvalues_page_size, will additionally limit 
    968    page size based on number of parameters total in the statement. 
    969 
    970 
    971    """ 
    972 
    973    preexecute_autoincrement_sequences: bool 
    974    """True if 'implicit' primary key functions must be executed separately 
    975      in order to get their value, if RETURNING is not used. 
    976 
    977      This is currently oriented towards PostgreSQL when the 
    978      ``implicit_returning=False`` parameter is used on a :class:`.Table` 
    979      object. 
    980 
    981    """ 
    982 
    983    insert_returning: bool 
    984    """if the dialect supports RETURNING with INSERT 
    985 
    986    .. versionadded:: 2.0 
    987 
    988    """ 
    989 
    990    update_returning: bool 
    991    """if the dialect supports RETURNING with UPDATE 
    992 
    993    .. versionadded:: 2.0 
    994 
    995    """ 
    996 
    997    update_returning_multifrom: bool 
    998    """if the dialect supports RETURNING with UPDATE..FROM 
    999 
    1000    .. versionadded:: 2.0 
    1001 
    1002    """ 
    1003 
    1004    delete_returning: bool 
    1005    """if the dialect supports RETURNING with DELETE 
    1006 
    1007    .. versionadded:: 2.0 
    1008 
    1009    """ 
    1010 
    1011    delete_returning_multifrom: bool 
    1012    """if the dialect supports RETURNING with DELETE..FROM 
    1013 
    1014    .. versionadded:: 2.0 
    1015 
    1016    """ 
    1017 
    1018    favor_returning_over_lastrowid: bool 
    1019    """for backends that support both a lastrowid and a RETURNING insert 
    1020    strategy, favor RETURNING for simple single-int pk inserts. 
    1021 
    1022    cursor.lastrowid tends to be more performant on most backends. 
    1023 
    1024    """ 
    1025 
    1026    supports_identity_columns: bool 
    1027    """target database supports IDENTITY""" 
    1028 
    1029    cte_follows_insert: bool 
    1030    """target database, when given a CTE with an INSERT statement, needs 
    1031    the CTE to be below the INSERT""" 
    1032 
    1033    colspecs: MutableMapping[Type[TypeEngine[Any]], Type[TypeEngine[Any]]] 
    1034    """A dictionary of TypeEngine classes from sqlalchemy.types mapped 
    1035      to subclasses that are specific to the dialect class.  This 
    1036      dictionary is class-level only and is not accessed from the 
    1037      dialect instance itself. 
    1038    """ 
    1039 
    1040    supports_sequences: bool 
    1041    """Indicates if the dialect supports CREATE SEQUENCE or similar.""" 
    1042 
    1043    sequences_optional: bool 
    1044    """If True, indicates if the :paramref:`_schema.Sequence.optional` 
    1045      parameter on the :class:`_schema.Sequence` construct 
    1046      should signal to not generate a CREATE SEQUENCE. Applies only to 
    1047      dialects that support sequences. Currently used only to allow PostgreSQL 
    1048      SERIAL to be used on a column that specifies Sequence() for usage on 
    1049      other backends. 
    1050    """ 
    1051 
    1052    default_sequence_base: int 
    1053    """the default value that will be rendered as the "START WITH" portion of 
    1054    a CREATE SEQUENCE DDL statement. 
    1055 
    1056    """ 
    1057 
    1058    supports_native_enum: bool 
    1059    """Indicates if the dialect supports a native ENUM construct. 
    1060      This will prevent :class:`_types.Enum` from generating a CHECK 
    1061      constraint when that type is used in "native" mode. 
    1062    """ 
    1063 
    1064    supports_native_boolean: bool 
    1065    """Indicates if the dialect supports a native boolean construct. 
    1066      This will prevent :class:`_types.Boolean` from generating a CHECK 
    1067      constraint when that type is used. 
    1068    """ 
    1069 
    1070    supports_native_decimal: bool 
    1071    """indicates if Decimal objects are handled and returned for precision 
    1072    numeric types, or if floats are returned""" 
    1073 
    1074    supports_native_uuid: bool 
    1075    """indicates if Python UUID() objects are handled natively by the 
    1076    driver for SQL UUID datatypes. 
    1077 
    1078    .. versionadded:: 2.0 
    1079 
    1080    """ 
    1081 
    1082    returns_native_bytes: bool 
    1083    """indicates if Python bytes() objects are returned natively by the 
    1084    driver for SQL "binary" datatypes. 
    1085 
    1086    .. versionadded:: 2.0.11 
    1087 
    1088    """ 
    1089 
    1090    construct_arguments: Optional[ 
    1091        List[Tuple[Type[Union[SchemaItem, ClauseElement]], Mapping[str, Any]]] 
    1092    ] = None 
    1093    """Optional set of argument specifiers for various SQLAlchemy 
    1094    constructs, typically schema items. 
    1095 
    1096    To implement, establish as a series of tuples, as in:: 
    1097 
    1098        construct_arguments = [ 
    1099            (schema.Index, {"using": False, "where": None, "ops": None}), 
    1100        ] 
    1101 
    1102    If the above construct is established on the PostgreSQL dialect, 
    1103    the :class:`.Index` construct will now accept the keyword arguments 
    1104    ``postgresql_using``, ``postgresql_where``, nad ``postgresql_ops``. 
    1105    Any other argument specified to the constructor of :class:`.Index` 
    1106    which is prefixed with ``postgresql_`` will raise :class:`.ArgumentError`. 
    1107 
    1108    A dialect which does not include a ``construct_arguments`` member will 
    1109    not participate in the argument validation system.  For such a dialect, 
    1110    any argument name is accepted by all participating constructs, within 
    1111    the namespace of arguments prefixed with that dialect name.  The rationale 
    1112    here is so that third-party dialects that haven't yet implemented this 
    1113    feature continue to function in the old way. 
    1114 
    1115    .. seealso:: 
    1116 
    1117        :class:`.DialectKWArgs` - implementing base class which consumes 
    1118        :attr:`.DefaultDialect.construct_arguments` 
    1119 
    1120 
    1121    """ 
    1122 
    1123    reflection_options: Sequence[str] = () 
    1124    """Sequence of string names indicating keyword arguments that can be 
    1125    established on a :class:`.Table` object which will be passed as 
    1126    "reflection options" when using :paramref:`.Table.autoload_with`. 
    1127 
    1128    Current example is "oracle_resolve_synonyms" in the Oracle Database 
    1129    dialects. 
    1130 
    1131    """ 
    1132 
    1133    dbapi_exception_translation_map: Mapping[str, str] = util.EMPTY_DICT 
    1134    """A dictionary of names that will contain as values the names of 
    1135       pep-249 exceptions ("IntegrityError", "OperationalError", etc) 
    1136       keyed to alternate class names, to support the case where a 
    1137       DBAPI has exception classes that aren't named as they are 
    1138       referred to (e.g. IntegrityError = MyException).   In the vast 
    1139       majority of cases this dictionary is empty. 
    1140    """ 
    1141 
    1142    supports_comments: bool 
    1143    """Indicates the dialect supports comment DDL on tables and columns.""" 
    1144 
    1145    inline_comments: bool 
    1146    """Indicates the dialect supports comment DDL that's inline with the 
    1147    definition of a Table or Column.  If False, this implies that ALTER must 
    1148    be used to set table and column comments.""" 
    1149 
    1150    supports_constraint_comments: bool 
    1151    """Indicates if the dialect supports comment DDL on constraints. 
    1152 
    1153    .. versionadded:: 2.0 
    1154    """ 
    1155 
    1156    _has_events = False 
    1157 
    1158    supports_statement_cache: bool = True 
    1159    """indicates if this dialect supports caching. 
    1160 
    1161    All dialects that are compatible with statement caching should set this 
    1162    flag to True directly on each dialect class and subclass that supports 
    1163    it.  SQLAlchemy tests that this flag is locally present on each dialect 
    1164    subclass before it will use statement caching.  This is to provide 
    1165    safety for legacy or new dialects that are not yet fully tested to be 
    1166    compliant with SQL statement caching. 
    1167 
    1168    .. versionadded:: 1.4.5 
    1169 
    1170    .. seealso:: 
    1171 
    1172        :ref:`engine_thirdparty_caching` 
    1173 
    1174    """ 
    1175 
    1176    _supports_statement_cache: bool 
    1177    """internal evaluation for supports_statement_cache""" 
    1178 
    1179    bind_typing = BindTyping.NONE 
    1180    """define a means of passing typing information to the database and/or 
    1181    driver for bound parameters. 
    1182 
    1183    See :class:`.BindTyping` for values. 
    1184 
    1185    .. versionadded:: 2.0 
    1186 
    1187    """ 
    1188 
    1189    is_async: bool 
    1190    """Whether or not this dialect is intended for asyncio use.""" 
    1191 
    1192    has_terminate: bool 
    1193    """Whether or not this dialect has a separate "terminate" implementation 
    1194    that does not block or require awaiting.""" 
    1195 
    1196    engine_config_types: Mapping[str, Any] 
    1197    """a mapping of string keys that can be in an engine config linked to 
    1198    type conversion functions. 
    1199 
    1200    """ 
    1201 
    1202    label_length: Optional[int] 
    1203    """optional user-defined max length for SQL labels""" 
    1204 
    1205    include_set_input_sizes: Optional[Set[Any]] 
    1206    """set of DBAPI type objects that should be included in 
    1207    automatic cursor.setinputsizes() calls. 
    1208 
    1209    This is only used if bind_typing is BindTyping.SET_INPUT_SIZES 
    1210 
    1211    """ 
    1212 
    1213    exclude_set_input_sizes: Optional[Set[Any]] 
    1214    """set of DBAPI type objects that should be excluded in 
    1215    automatic cursor.setinputsizes() calls. 
    1216 
    1217    This is only used if bind_typing is BindTyping.SET_INPUT_SIZES 
    1218 
    1219    """ 
    1220 
    1221    supports_simple_order_by_label: bool 
    1222    """target database supports ORDER BY <labelname>, where <labelname> 
    1223    refers to a label in the columns clause of the SELECT""" 
    1224 
    1225    div_is_floordiv: bool 
    1226    """target database treats the / division operator as "floor division" """ 
    1227 
    1228    tuple_in_values: bool 
    1229    """target database supports tuple IN, i.e. (x, y) IN ((q, p), (r, z))""" 
    1230 
    1231    requires_name_normalize: bool 
    1232    """Indicates symbol names are returned by the database in 
    1233    UPPERCASED if they are case insensitive within the database. 
    1234    If this is True, the methods normalize_name() 
    1235    and denormalize_name() must be provided. 
    1236    """ 
    1237 
    1238    _bind_typing_render_casts: bool 
    1239 
    1240    _type_memos: MutableMapping[TypeEngine[Any], _TypeMemoDict] 
    1241 
    1242    def _builtin_onconnect(self) -> Optional[_ListenerFnType]: 
    1243        raise NotImplementedError() 
    1244 
    1245    def create_connect_args(self, url: URL) -> ConnectArgsType: 
    1246        """Build DB-API compatible connection arguments. 
    1247 
    1248        Given a :class:`.URL` object, returns a tuple 
    1249        consisting of a ``(*args, **kwargs)`` suitable to send directly 
    1250        to the dbapi's connect function.   The arguments are sent to the 
    1251        :meth:`.Dialect.connect` method which then runs the DBAPI-level 
    1252        ``connect()`` function. 
    1253 
    1254        The method typically makes use of the 
    1255        :meth:`.URL.translate_connect_args` 
    1256        method in order to generate a dictionary of options. 
    1257 
    1258        The default implementation is:: 
    1259 
    1260            def create_connect_args(self, url): 
    1261                opts = url.translate_connect_args() 
    1262                opts.update(url.query) 
    1263                return ([], opts) 
    1264 
    1265        :param url: a :class:`.URL` object 
    1266 
    1267        :return: a tuple of ``(*args, **kwargs)`` which will be passed to the 
    1268         :meth:`.Dialect.connect` method. 
    1269 
    1270        .. seealso:: 
    1271 
    1272            :meth:`.URL.translate_connect_args` 
    1273 
    1274        """ 
    1275 
    1276        raise NotImplementedError() 
    1277 
    1278    @classmethod 
    1279    def import_dbapi(cls) -> DBAPIModule: 
    1280        """Import the DBAPI module that is used by this dialect. 
    1281 
    1282        The Python module object returned here will be assigned as an 
    1283        instance variable to a constructed dialect under the name 
    1284        ``.dbapi``. 
    1285 
    1286        .. versionchanged:: 2.0  The :meth:`.Dialect.import_dbapi` class 
    1287           method is renamed from the previous method ``.Dialect.dbapi()``, 
    1288           which would be replaced at dialect instantiation time by the 
    1289           DBAPI module itself, thus using the same name in two different ways. 
    1290           If a ``.Dialect.dbapi()`` classmethod is present on a third-party 
    1291           dialect, it will be used and a deprecation warning will be emitted. 
    1292 
    1293        """ 
    1294        raise NotImplementedError() 
    1295 
    1296    def type_descriptor(self, typeobj: TypeEngine[_T]) -> TypeEngine[_T]: 
    1297        """Transform a generic type to a dialect-specific type. 
    1298 
    1299        Dialect classes will usually use the 
    1300        :func:`_types.adapt_type` function in the types module to 
    1301        accomplish this. 
    1302 
    1303        The returned result is cached *per dialect class* so can 
    1304        contain no dialect-instance state. 
    1305 
    1306        """ 
    1307 
    1308        raise NotImplementedError() 
    1309 
    1310    def initialize(self, connection: Connection) -> None: 
    1311        """Called during strategized creation of the dialect with a 
    1312        connection. 
    1313 
    1314        Allows dialects to configure options based on server version info or 
    1315        other properties. 
    1316 
    1317        The connection passed here is a SQLAlchemy Connection object, 
    1318        with full capabilities. 
    1319 
    1320        The initialize() method of the base dialect should be called via 
    1321        super(). 
    1322 
    1323        .. note:: as of SQLAlchemy 1.4, this method is called **before** 
    1324           any :meth:`_engine.Dialect.on_connect` hooks are called. 
    1325 
    1326        """ 
    1327 
    1328    if TYPE_CHECKING: 
    1329 
    1330        def _overrides_default(self, method_name: str) -> bool: ... 
    1331 
    1332    def get_columns( 
    1333        self, 
    1334        connection: Connection, 
    1335        table_name: str, 
    1336        schema: Optional[str] = None, 
    1337        **kw: Any, 
    1338    ) -> List[ReflectedColumn]: 
    1339        """Return information about columns in ``table_name``. 
    1340 
    1341        Given a :class:`_engine.Connection`, a string 
    1342        ``table_name``, and an optional string ``schema``, return column 
    1343        information as a list of dictionaries 
    1344        corresponding to the :class:`.ReflectedColumn` dictionary. 
    1345 
    1346        This is an internal dialect method. Applications should use 
    1347        :meth:`.Inspector.get_columns`. 
    1348 
    1349        """ 
    1350 
    1351        raise NotImplementedError() 
    1352 
    1353    def get_multi_columns( 
    1354        self, 
    1355        connection: Connection, 
    1356        *, 
    1357        schema: Optional[str] = None, 
    1358        filter_names: Optional[Collection[str]] = None, 
    1359        **kw: Any, 
    1360    ) -> Iterable[Tuple[TableKey, List[ReflectedColumn]]]: 
    1361        """Return information about columns in all tables in the 
    1362        given ``schema``. 
    1363 
    1364        This is an internal dialect method. Applications should use 
    1365        :meth:`.Inspector.get_multi_columns`. 
    1366 
    1367        .. note:: The :class:`_engine.DefaultDialect` provides a default 
    1368          implementation that will call the single table method for 
    1369          each object returned by :meth:`Dialect.get_table_names`, 
    1370          :meth:`Dialect.get_view_names` or 
    1371          :meth:`Dialect.get_materialized_view_names` depending on the 
    1372          provided ``kind``. Dialects that want to support a faster 
    1373          implementation should implement this method. 
    1374 
    1375        .. versionadded:: 2.0 
    1376 
    1377        """ 
    1378 
    1379        raise NotImplementedError() 
    1380 
    1381    def get_pk_constraint( 
    1382        self, 
    1383        connection: Connection, 
    1384        table_name: str, 
    1385        schema: Optional[str] = None, 
    1386        **kw: Any, 
    1387    ) -> ReflectedPrimaryKeyConstraint: 
    1388        """Return information about the primary key constraint on 
    1389        table_name`. 
    1390 
    1391        Given a :class:`_engine.Connection`, a string 
    1392        ``table_name``, and an optional string ``schema``, return primary 
    1393        key information as a dictionary corresponding to the 
    1394        :class:`.ReflectedPrimaryKeyConstraint` dictionary. 
    1395 
    1396        This is an internal dialect method. Applications should use 
    1397        :meth:`.Inspector.get_pk_constraint`. 
    1398 
    1399        """ 
    1400        raise NotImplementedError() 
    1401 
    1402    def get_multi_pk_constraint( 
    1403        self, 
    1404        connection: Connection, 
    1405        *, 
    1406        schema: Optional[str] = None, 
    1407        filter_names: Optional[Collection[str]] = None, 
    1408        **kw: Any, 
    1409    ) -> Iterable[Tuple[TableKey, ReflectedPrimaryKeyConstraint]]: 
    1410        """Return information about primary key constraints in 
    1411        all tables in the given ``schema``. 
    1412 
    1413        This is an internal dialect method. Applications should use 
    1414        :meth:`.Inspector.get_multi_pk_constraint`. 
    1415 
    1416        .. note:: The :class:`_engine.DefaultDialect` provides a default 
    1417          implementation that will call the single table method for 
    1418          each object returned by :meth:`Dialect.get_table_names`, 
    1419          :meth:`Dialect.get_view_names` or 
    1420          :meth:`Dialect.get_materialized_view_names` depending on the 
    1421          provided ``kind``. Dialects that want to support a faster 
    1422          implementation should implement this method. 
    1423 
    1424        .. versionadded:: 2.0 
    1425 
    1426        """ 
    1427        raise NotImplementedError() 
    1428 
    1429    def get_foreign_keys( 
    1430        self, 
    1431        connection: Connection, 
    1432        table_name: str, 
    1433        schema: Optional[str] = None, 
    1434        **kw: Any, 
    1435    ) -> List[ReflectedForeignKeyConstraint]: 
    1436        """Return information about foreign_keys in ``table_name``. 
    1437 
    1438        Given a :class:`_engine.Connection`, a string 
    1439        ``table_name``, and an optional string ``schema``, return foreign 
    1440        key information as a list of dicts corresponding to the 
    1441        :class:`.ReflectedForeignKeyConstraint` dictionary. 
    1442 
    1443        This is an internal dialect method. Applications should use 
    1444        :meth:`_engine.Inspector.get_foreign_keys`. 
    1445        """ 
    1446 
    1447        raise NotImplementedError() 
    1448 
    1449    def get_multi_foreign_keys( 
    1450        self, 
    1451        connection: Connection, 
    1452        *, 
    1453        schema: Optional[str] = None, 
    1454        filter_names: Optional[Collection[str]] = None, 
    1455        **kw: Any, 
    1456    ) -> Iterable[Tuple[TableKey, List[ReflectedForeignKeyConstraint]]]: 
    1457        """Return information about foreign_keys in all tables 
    1458        in the given ``schema``. 
    1459 
    1460        This is an internal dialect method. Applications should use 
    1461        :meth:`_engine.Inspector.get_multi_foreign_keys`. 
    1462 
    1463        .. note:: The :class:`_engine.DefaultDialect` provides a default 
    1464          implementation that will call the single table method for 
    1465          each object returned by :meth:`Dialect.get_table_names`, 
    1466          :meth:`Dialect.get_view_names` or 
    1467          :meth:`Dialect.get_materialized_view_names` depending on the 
    1468          provided ``kind``. Dialects that want to support a faster 
    1469          implementation should implement this method. 
    1470 
    1471        .. versionadded:: 2.0 
    1472 
    1473        """ 
    1474 
    1475        raise NotImplementedError() 
    1476 
    1477    def get_table_names( 
    1478        self, connection: Connection, schema: Optional[str] = None, **kw: Any 
    1479    ) -> List[str]: 
    1480        """Return a list of table names for ``schema``. 
    1481 
    1482        This is an internal dialect method. Applications should use 
    1483        :meth:`_engine.Inspector.get_table_names`. 
    1484 
    1485        """ 
    1486 
    1487        raise NotImplementedError() 
    1488 
    1489    def get_temp_table_names( 
    1490        self, connection: Connection, schema: Optional[str] = None, **kw: Any 
    1491    ) -> List[str]: 
    1492        """Return a list of temporary table names on the given connection, 
    1493        if supported by the underlying backend. 
    1494 
    1495        This is an internal dialect method. Applications should use 
    1496        :meth:`_engine.Inspector.get_temp_table_names`. 
    1497 
    1498        """ 
    1499 
    1500        raise NotImplementedError() 
    1501 
    1502    def get_view_names( 
    1503        self, connection: Connection, schema: Optional[str] = None, **kw: Any 
    1504    ) -> List[str]: 
    1505        """Return a list of all non-materialized view names available in the 
    1506        database. 
    1507 
    1508        This is an internal dialect method. Applications should use 
    1509        :meth:`_engine.Inspector.get_view_names`. 
    1510 
    1511        :param schema: schema name to query, if not the default schema. 
    1512 
    1513        """ 
    1514 
    1515        raise NotImplementedError() 
    1516 
    1517    def get_materialized_view_names( 
    1518        self, connection: Connection, schema: Optional[str] = None, **kw: Any 
    1519    ) -> List[str]: 
    1520        """Return a list of all materialized view names available in the 
    1521        database. 
    1522 
    1523        This is an internal dialect method. Applications should use 
    1524        :meth:`_engine.Inspector.get_materialized_view_names`. 
    1525 
    1526        :param schema: schema name to query, if not the default schema. 
    1527 
    1528         .. versionadded:: 2.0 
    1529 
    1530        """ 
    1531 
    1532        raise NotImplementedError() 
    1533 
    1534    def get_sequence_names( 
    1535        self, connection: Connection, schema: Optional[str] = None, **kw: Any 
    1536    ) -> List[str]: 
    1537        """Return a list of all sequence names available in the database. 
    1538 
    1539        This is an internal dialect method. Applications should use 
    1540        :meth:`_engine.Inspector.get_sequence_names`. 
    1541 
    1542        :param schema: schema name to query, if not the default schema. 
    1543 
    1544        .. versionadded:: 1.4 
    1545        """ 
    1546 
    1547        raise NotImplementedError() 
    1548 
    1549    def get_temp_view_names( 
    1550        self, connection: Connection, schema: Optional[str] = None, **kw: Any 
    1551    ) -> List[str]: 
    1552        """Return a list of temporary view names on the given connection, 
    1553        if supported by the underlying backend. 
    1554 
    1555        This is an internal dialect method. Applications should use 
    1556        :meth:`_engine.Inspector.get_temp_view_names`. 
    1557 
    1558        """ 
    1559 
    1560        raise NotImplementedError() 
    1561 
    1562    def get_schema_names(self, connection: Connection, **kw: Any) -> List[str]: 
    1563        """Return a list of all schema names available in the database. 
    1564 
    1565        This is an internal dialect method. Applications should use 
    1566        :meth:`_engine.Inspector.get_schema_names`. 
    1567        """ 
    1568        raise NotImplementedError() 
    1569 
    1570    def get_view_definition( 
    1571        self, 
    1572        connection: Connection, 
    1573        view_name: str, 
    1574        schema: Optional[str] = None, 
    1575        **kw: Any, 
    1576    ) -> str: 
    1577        """Return plain or materialized view definition. 
    1578 
    1579        This is an internal dialect method. Applications should use 
    1580        :meth:`_engine.Inspector.get_view_definition`. 
    1581 
    1582        Given a :class:`_engine.Connection`, a string 
    1583        ``view_name``, and an optional string ``schema``, return the view 
    1584        definition. 
    1585        """ 
    1586 
    1587        raise NotImplementedError() 
    1588 
    1589    def get_indexes( 
    1590        self, 
    1591        connection: Connection, 
    1592        table_name: str, 
    1593        schema: Optional[str] = None, 
    1594        **kw: Any, 
    1595    ) -> List[ReflectedIndex]: 
    1596        """Return information about indexes in ``table_name``. 
    1597 
    1598        Given a :class:`_engine.Connection`, a string 
    1599        ``table_name`` and an optional string ``schema``, return index 
    1600        information as a list of dictionaries corresponding to the 
    1601        :class:`.ReflectedIndex` dictionary. 
    1602 
    1603        This is an internal dialect method. Applications should use 
    1604        :meth:`.Inspector.get_indexes`. 
    1605        """ 
    1606 
    1607        raise NotImplementedError() 
    1608 
    1609    def get_multi_indexes( 
    1610        self, 
    1611        connection: Connection, 
    1612        *, 
    1613        schema: Optional[str] = None, 
    1614        filter_names: Optional[Collection[str]] = None, 
    1615        **kw: Any, 
    1616    ) -> Iterable[Tuple[TableKey, List[ReflectedIndex]]]: 
    1617        """Return information about indexes in in all tables 
    1618        in the given ``schema``. 
    1619 
    1620        This is an internal dialect method. Applications should use 
    1621        :meth:`.Inspector.get_multi_indexes`. 
    1622 
    1623        .. note:: The :class:`_engine.DefaultDialect` provides a default 
    1624          implementation that will call the single table method for 
    1625          each object returned by :meth:`Dialect.get_table_names`, 
    1626          :meth:`Dialect.get_view_names` or 
    1627          :meth:`Dialect.get_materialized_view_names` depending on the 
    1628          provided ``kind``. Dialects that want to support a faster 
    1629          implementation should implement this method. 
    1630 
    1631        .. versionadded:: 2.0 
    1632 
    1633        """ 
    1634 
    1635        raise NotImplementedError() 
    1636 
    1637    def get_unique_constraints( 
    1638        self, 
    1639        connection: Connection, 
    1640        table_name: str, 
    1641        schema: Optional[str] = None, 
    1642        **kw: Any, 
    1643    ) -> List[ReflectedUniqueConstraint]: 
    1644        r"""Return information about unique constraints in ``table_name``. 
    1645 
    1646        Given a string ``table_name`` and an optional string ``schema``, return 
    1647        unique constraint information as a list of dicts corresponding 
    1648        to the :class:`.ReflectedUniqueConstraint` dictionary. 
    1649 
    1650        This is an internal dialect method. Applications should use 
    1651        :meth:`.Inspector.get_unique_constraints`. 
    1652        """ 
    1653 
    1654        raise NotImplementedError() 
    1655 
    1656    def get_multi_unique_constraints( 
    1657        self, 
    1658        connection: Connection, 
    1659        *, 
    1660        schema: Optional[str] = None, 
    1661        filter_names: Optional[Collection[str]] = None, 
    1662        **kw: Any, 
    1663    ) -> Iterable[Tuple[TableKey, List[ReflectedUniqueConstraint]]]: 
    1664        """Return information about unique constraints in all tables 
    1665        in the given ``schema``. 
    1666 
    1667        This is an internal dialect method. Applications should use 
    1668        :meth:`.Inspector.get_multi_unique_constraints`. 
    1669 
    1670        .. note:: The :class:`_engine.DefaultDialect` provides a default 
    1671          implementation that will call the single table method for 
    1672          each object returned by :meth:`Dialect.get_table_names`, 
    1673          :meth:`Dialect.get_view_names` or 
    1674          :meth:`Dialect.get_materialized_view_names` depending on the 
    1675          provided ``kind``. Dialects that want to support a faster 
    1676          implementation should implement this method. 
    1677 
    1678        .. versionadded:: 2.0 
    1679 
    1680        """ 
    1681 
    1682        raise NotImplementedError() 
    1683 
    1684    def get_check_constraints( 
    1685        self, 
    1686        connection: Connection, 
    1687        table_name: str, 
    1688        schema: Optional[str] = None, 
    1689        **kw: Any, 
    1690    ) -> List[ReflectedCheckConstraint]: 
    1691        r"""Return information about check constraints in ``table_name``. 
    1692 
    1693        Given a string ``table_name`` and an optional string ``schema``, return 
    1694        check constraint information as a list of dicts corresponding 
    1695        to the :class:`.ReflectedCheckConstraint` dictionary. 
    1696 
    1697        This is an internal dialect method. Applications should use 
    1698        :meth:`.Inspector.get_check_constraints`. 
    1699 
    1700        """ 
    1701 
    1702        raise NotImplementedError() 
    1703 
    1704    def get_multi_check_constraints( 
    1705        self, 
    1706        connection: Connection, 
    1707        *, 
    1708        schema: Optional[str] = None, 
    1709        filter_names: Optional[Collection[str]] = None, 
    1710        **kw: Any, 
    1711    ) -> Iterable[Tuple[TableKey, List[ReflectedCheckConstraint]]]: 
    1712        """Return information about check constraints in all tables 
    1713        in the given ``schema``. 
    1714 
    1715        This is an internal dialect method. Applications should use 
    1716        :meth:`.Inspector.get_multi_check_constraints`. 
    1717 
    1718        .. note:: The :class:`_engine.DefaultDialect` provides a default 
    1719          implementation that will call the single table method for 
    1720          each object returned by :meth:`Dialect.get_table_names`, 
    1721          :meth:`Dialect.get_view_names` or 
    1722          :meth:`Dialect.get_materialized_view_names` depending on the 
    1723          provided ``kind``. Dialects that want to support a faster 
    1724          implementation should implement this method. 
    1725 
    1726        .. versionadded:: 2.0 
    1727 
    1728        """ 
    1729 
    1730        raise NotImplementedError() 
    1731 
    1732    def get_table_options( 
    1733        self, 
    1734        connection: Connection, 
    1735        table_name: str, 
    1736        schema: Optional[str] = None, 
    1737        **kw: Any, 
    1738    ) -> Dict[str, Any]: 
    1739        """Return a dictionary of options specified when ``table_name`` 
    1740        was created. 
    1741 
    1742        This is an internal dialect method. Applications should use 
    1743        :meth:`_engine.Inspector.get_table_options`. 
    1744        """ 
    1745        raise NotImplementedError() 
    1746 
    1747    def get_multi_table_options( 
    1748        self, 
    1749        connection: Connection, 
    1750        *, 
    1751        schema: Optional[str] = None, 
    1752        filter_names: Optional[Collection[str]] = None, 
    1753        **kw: Any, 
    1754    ) -> Iterable[Tuple[TableKey, Dict[str, Any]]]: 
    1755        """Return a dictionary of options specified when the tables in the 
    1756        given schema were created. 
    1757 
    1758        This is an internal dialect method. Applications should use 
    1759        :meth:`_engine.Inspector.get_multi_table_options`. 
    1760 
    1761        .. note:: The :class:`_engine.DefaultDialect` provides a default 
    1762          implementation that will call the single table method for 
    1763          each object returned by :meth:`Dialect.get_table_names`, 
    1764          :meth:`Dialect.get_view_names` or 
    1765          :meth:`Dialect.get_materialized_view_names` depending on the 
    1766          provided ``kind``. Dialects that want to support a faster 
    1767          implementation should implement this method. 
    1768 
    1769        .. versionadded:: 2.0 
    1770 
    1771        """ 
    1772        raise NotImplementedError() 
    1773 
    1774    def get_table_comment( 
    1775        self, 
    1776        connection: Connection, 
    1777        table_name: str, 
    1778        schema: Optional[str] = None, 
    1779        **kw: Any, 
    1780    ) -> ReflectedTableComment: 
    1781        r"""Return the "comment" for the table identified by ``table_name``. 
    1782 
    1783        Given a string ``table_name`` and an optional string ``schema``, return 
    1784        table comment information as a dictionary corresponding to the 
    1785        :class:`.ReflectedTableComment` dictionary. 
    1786 
    1787        This is an internal dialect method. Applications should use 
    1788        :meth:`.Inspector.get_table_comment`. 
    1789 
    1790        :raise: ``NotImplementedError`` for dialects that don't support 
    1791         comments. 
    1792 
    1793        """ 
    1794 
    1795        raise NotImplementedError() 
    1796 
    1797    def get_multi_table_comment( 
    1798        self, 
    1799        connection: Connection, 
    1800        *, 
    1801        schema: Optional[str] = None, 
    1802        filter_names: Optional[Collection[str]] = None, 
    1803        **kw: Any, 
    1804    ) -> Iterable[Tuple[TableKey, ReflectedTableComment]]: 
    1805        """Return information about the table comment in all tables 
    1806        in the given ``schema``. 
    1807 
    1808        This is an internal dialect method. Applications should use 
    1809        :meth:`_engine.Inspector.get_multi_table_comment`. 
    1810 
    1811        .. note:: The :class:`_engine.DefaultDialect` provides a default 
    1812          implementation that will call the single table method for 
    1813          each object returned by :meth:`Dialect.get_table_names`, 
    1814          :meth:`Dialect.get_view_names` or 
    1815          :meth:`Dialect.get_materialized_view_names` depending on the 
    1816          provided ``kind``. Dialects that want to support a faster 
    1817          implementation should implement this method. 
    1818 
    1819        .. versionadded:: 2.0 
    1820 
    1821        """ 
    1822 
    1823        raise NotImplementedError() 
    1824 
    1825    def normalize_name(self, name: str) -> str: 
    1826        """convert the given name to lowercase if it is detected as 
    1827        case insensitive. 
    1828 
    1829        This method is only used if the dialect defines 
    1830        requires_name_normalize=True. 
    1831 
    1832        """ 
    1833        raise NotImplementedError() 
    1834 
    1835    def denormalize_name(self, name: str) -> str: 
    1836        """convert the given name to a case insensitive identifier 
    1837        for the backend if it is an all-lowercase name. 
    1838 
    1839        This method is only used if the dialect defines 
    1840        requires_name_normalize=True. 
    1841 
    1842        """ 
    1843        raise NotImplementedError() 
    1844 
    1845    def has_table( 
    1846        self, 
    1847        connection: Connection, 
    1848        table_name: str, 
    1849        schema: Optional[str] = None, 
    1850        **kw: Any, 
    1851    ) -> bool: 
    1852        """For internal dialect use, check the existence of a particular table 
    1853        or view in the database. 
    1854 
    1855        Given a :class:`_engine.Connection` object, a string table_name and 
    1856        optional schema name, return True if the given table exists in the 
    1857        database, False otherwise. 
    1858 
    1859        This method serves as the underlying implementation of the 
    1860        public facing :meth:`.Inspector.has_table` method, and is also used 
    1861        internally to implement the "checkfirst" behavior for methods like 
    1862        :meth:`_schema.Table.create` and :meth:`_schema.MetaData.create_all`. 
    1863 
    1864        .. note:: This method is used internally by SQLAlchemy, and is 
    1865           published so that third-party dialects may provide an 
    1866           implementation. It is **not** the public API for checking for table 
    1867           presence. Please use the :meth:`.Inspector.has_table` method. 
    1868 
    1869        .. versionchanged:: 2.0:: :meth:`_engine.Dialect.has_table` now 
    1870           formally supports checking for additional table-like objects: 
    1871 
    1872           * any type of views (plain or materialized) 
    1873           * temporary tables of any kind 
    1874 
    1875           Previously, these two checks were not formally specified and 
    1876           different dialects would vary in their behavior.   The dialect 
    1877           testing suite now includes tests for all of these object types, 
    1878           and dialects to the degree that the backing database supports views 
    1879           or temporary tables should seek to support locating these objects 
    1880           for full compliance. 
    1881 
    1882        """ 
    1883 
    1884        raise NotImplementedError() 
    1885 
    1886    def has_index( 
    1887        self, 
    1888        connection: Connection, 
    1889        table_name: str, 
    1890        index_name: str, 
    1891        schema: Optional[str] = None, 
    1892        **kw: Any, 
    1893    ) -> bool: 
    1894        """Check the existence of a particular index name in the database. 
    1895 
    1896        Given a :class:`_engine.Connection` object, a string 
    1897        ``table_name`` and string index name, return ``True`` if an index of 
    1898        the given name on the given table exists, ``False`` otherwise. 
    1899 
    1900        The :class:`.DefaultDialect` implements this in terms of the 
    1901        :meth:`.Dialect.has_table` and :meth:`.Dialect.get_indexes` methods, 
    1902        however dialects can implement a more performant version. 
    1903 
    1904        This is an internal dialect method. Applications should use 
    1905        :meth:`_engine.Inspector.has_index`. 
    1906 
    1907        .. versionadded:: 1.4 
    1908 
    1909        """ 
    1910 
    1911        raise NotImplementedError() 
    1912 
    1913    def has_sequence( 
    1914        self, 
    1915        connection: Connection, 
    1916        sequence_name: str, 
    1917        schema: Optional[str] = None, 
    1918        **kw: Any, 
    1919    ) -> bool: 
    1920        """Check the existence of a particular sequence in the database. 
    1921 
    1922        Given a :class:`_engine.Connection` object and a string 
    1923        `sequence_name`, return ``True`` if the given sequence exists in 
    1924        the database, ``False`` otherwise. 
    1925 
    1926        This is an internal dialect method. Applications should use 
    1927        :meth:`_engine.Inspector.has_sequence`. 
    1928        """ 
    1929 
    1930        raise NotImplementedError() 
    1931 
    1932    def has_schema( 
    1933        self, connection: Connection, schema_name: str, **kw: Any 
    1934    ) -> bool: 
    1935        """Check the existence of a particular schema name in the database. 
    1936 
    1937        Given a :class:`_engine.Connection` object, a string 
    1938        ``schema_name``, return ``True`` if a schema of the 
    1939        given exists, ``False`` otherwise. 
    1940 
    1941        The :class:`.DefaultDialect` implements this by checking 
    1942        the presence of ``schema_name`` among the schemas returned by 
    1943        :meth:`.Dialect.get_schema_names`, 
    1944        however dialects can implement a more performant version. 
    1945 
    1946        This is an internal dialect method. Applications should use 
    1947        :meth:`_engine.Inspector.has_schema`. 
    1948 
    1949        .. versionadded:: 2.0 
    1950 
    1951        """ 
    1952 
    1953        raise NotImplementedError() 
    1954 
    1955    def _get_server_version_info(self, connection: Connection) -> Any: 
    1956        """Retrieve the server version info from the given connection. 
    1957 
    1958        This is used by the default implementation to populate the 
    1959        "server_version_info" attribute and is called exactly 
    1960        once upon first connect. 
    1961 
    1962        """ 
    1963 
    1964        raise NotImplementedError() 
    1965 
    1966    def _get_default_schema_name(self, connection: Connection) -> str: 
    1967        """Return the string name of the currently selected schema from 
    1968        the given connection. 
    1969 
    1970        This is used by the default implementation to populate the 
    1971        "default_schema_name" attribute and is called exactly 
    1972        once upon first connect. 
    1973 
    1974        """ 
    1975 
    1976        raise NotImplementedError() 
    1977 
    1978    def do_begin(self, dbapi_connection: PoolProxiedConnection) -> None: 
    1979        """Provide an implementation of ``connection.begin()``, given a 
    1980        DB-API connection. 
    1981 
    1982        The DBAPI has no dedicated "begin" method and it is expected 
    1983        that transactions are implicit.  This hook is provided for those 
    1984        DBAPIs that might need additional help in this area. 
    1985 
    1986        :param dbapi_connection: a DBAPI connection, typically 
    1987         proxied within a :class:`.ConnectionFairy`. 
    1988 
    1989        """ 
    1990 
    1991        raise NotImplementedError() 
    1992 
    1993    def do_rollback(self, dbapi_connection: PoolProxiedConnection) -> None: 
    1994        """Provide an implementation of ``connection.rollback()``, given 
    1995        a DB-API connection. 
    1996 
    1997        :param dbapi_connection: a DBAPI connection, typically 
    1998         proxied within a :class:`.ConnectionFairy`. 
    1999 
    2000        """ 
    2001 
    2002        raise NotImplementedError() 
    2003 
    2004    def do_commit(self, dbapi_connection: PoolProxiedConnection) -> None: 
    2005        """Provide an implementation of ``connection.commit()``, given a 
    2006        DB-API connection. 
    2007 
    2008        :param dbapi_connection: a DBAPI connection, typically 
    2009         proxied within a :class:`.ConnectionFairy`. 
    2010 
    2011        """ 
    2012 
    2013        raise NotImplementedError() 
    2014 
    2015    def do_terminate(self, dbapi_connection: DBAPIConnection) -> None: 
    2016        """Provide an implementation of ``connection.close()`` that tries as 
    2017        much as possible to not block, given a DBAPI 
    2018        connection. 
    2019 
    2020        In the vast majority of cases this just calls .close(), however 
    2021        for some asyncio dialects may call upon different API features. 
    2022 
    2023        This hook is called by the :class:`_pool.Pool` 
    2024        when a connection is being recycled or has been invalidated. 
    2025 
    2026        .. versionadded:: 1.4.41 
    2027 
    2028        """ 
    2029 
    2030        raise NotImplementedError() 
    2031 
    2032    def do_close(self, dbapi_connection: DBAPIConnection) -> None: 
    2033        """Provide an implementation of ``connection.close()``, given a DBAPI 
    2034        connection. 
    2035 
    2036        This hook is called by the :class:`_pool.Pool` 
    2037        when a connection has been 
    2038        detached from the pool, or is being returned beyond the normal 
    2039        capacity of the pool. 
    2040 
    2041        """ 
    2042 
    2043        raise NotImplementedError() 
    2044 
    2045    def _do_ping_w_event(self, dbapi_connection: DBAPIConnection) -> bool: 
    2046        raise NotImplementedError() 
    2047 
    2048    def do_ping(self, dbapi_connection: DBAPIConnection) -> bool: 
    2049        """ping the DBAPI connection and return True if the connection is 
    2050        usable.""" 
    2051        raise NotImplementedError() 
    2052 
    2053    def do_set_input_sizes( 
    2054        self, 
    2055        cursor: DBAPICursor, 
    2056        list_of_tuples: _GenericSetInputSizesType, 
    2057        context: ExecutionContext, 
    2058    ) -> Any: 
    2059        """invoke the cursor.setinputsizes() method with appropriate arguments 
    2060 
    2061        This hook is called if the :attr:`.Dialect.bind_typing` attribute is 
    2062        set to the 
    2063        :attr:`.BindTyping.SETINPUTSIZES` value. 
    2064        Parameter data is passed in a list of tuples (paramname, dbtype, 
    2065        sqltype), where ``paramname`` is the key of the parameter in the 
    2066        statement, ``dbtype`` is the DBAPI datatype and ``sqltype`` is the 
    2067        SQLAlchemy type. The order of tuples is in the correct parameter order. 
    2068 
    2069        .. versionadded:: 1.4 
    2070 
    2071        .. versionchanged:: 2.0  - setinputsizes mode is now enabled by 
    2072           setting :attr:`.Dialect.bind_typing` to 
    2073           :attr:`.BindTyping.SETINPUTSIZES`.  Dialects which accept 
    2074           a ``use_setinputsizes`` parameter should set this value 
    2075           appropriately. 
    2076 
    2077 
    2078        """ 
    2079        raise NotImplementedError() 
    2080 
    2081    def create_xid(self) -> Any: 
    2082        """Create a two-phase transaction ID. 
    2083 
    2084        This id will be passed to do_begin_twophase(), 
    2085        do_rollback_twophase(), do_commit_twophase().  Its format is 
    2086        unspecified. 
    2087        """ 
    2088 
    2089        raise NotImplementedError() 
    2090 
    2091    def do_savepoint(self, connection: Connection, name: str) -> None: 
    2092        """Create a savepoint with the given name. 
    2093 
    2094        :param connection: a :class:`_engine.Connection`. 
    2095        :param name: savepoint name. 
    2096 
    2097        """ 
    2098 
    2099        raise NotImplementedError() 
    2100 
    2101    def do_rollback_to_savepoint( 
    2102        self, connection: Connection, name: str 
    2103    ) -> None: 
    2104        """Rollback a connection to the named savepoint. 
    2105 
    2106        :param connection: a :class:`_engine.Connection`. 
    2107        :param name: savepoint name. 
    2108 
    2109        """ 
    2110 
    2111        raise NotImplementedError() 
    2112 
    2113    def do_release_savepoint(self, connection: Connection, name: str) -> None: 
    2114        """Release the named savepoint on a connection. 
    2115 
    2116        :param connection: a :class:`_engine.Connection`. 
    2117        :param name: savepoint name. 
    2118        """ 
    2119 
    2120        raise NotImplementedError() 
    2121 
    2122    def do_begin_twophase(self, connection: Connection, xid: Any) -> None: 
    2123        """Begin a two phase transaction on the given connection. 
    2124 
    2125        :param connection: a :class:`_engine.Connection`. 
    2126        :param xid: xid 
    2127 
    2128        """ 
    2129 
    2130        raise NotImplementedError() 
    2131 
    2132    def do_prepare_twophase(self, connection: Connection, xid: Any) -> None: 
    2133        """Prepare a two phase transaction on the given connection. 
    2134 
    2135        :param connection: a :class:`_engine.Connection`. 
    2136        :param xid: xid 
    2137 
    2138        """ 
    2139 
    2140        raise NotImplementedError() 
    2141 
    2142    def do_rollback_twophase( 
    2143        self, 
    2144        connection: Connection, 
    2145        xid: Any, 
    2146        is_prepared: bool = True, 
    2147        recover: bool = False, 
    2148    ) -> None: 
    2149        """Rollback a two phase transaction on the given connection. 
    2150 
    2151        :param connection: a :class:`_engine.Connection`. 
    2152        :param xid: xid 
    2153        :param is_prepared: whether or not 
    2154         :meth:`.TwoPhaseTransaction.prepare` was called. 
    2155        :param recover: if the recover flag was passed. 
    2156 
    2157        """ 
    2158 
    2159        raise NotImplementedError() 
    2160 
    2161    def do_commit_twophase( 
    2162        self, 
    2163        connection: Connection, 
    2164        xid: Any, 
    2165        is_prepared: bool = True, 
    2166        recover: bool = False, 
    2167    ) -> None: 
    2168        """Commit a two phase transaction on the given connection. 
    2169 
    2170 
    2171        :param connection: a :class:`_engine.Connection`. 
    2172        :param xid: xid 
    2173        :param is_prepared: whether or not 
    2174         :meth:`.TwoPhaseTransaction.prepare` was called. 
    2175        :param recover: if the recover flag was passed. 
    2176 
    2177        """ 
    2178 
    2179        raise NotImplementedError() 
    2180 
    2181    def do_recover_twophase(self, connection: Connection) -> List[Any]: 
    2182        """Recover list of uncommitted prepared two phase transaction 
    2183        identifiers on the given connection. 
    2184 
    2185        :param connection: a :class:`_engine.Connection`. 
    2186 
    2187        """ 
    2188 
    2189        raise NotImplementedError() 
    2190 
    2191    def _deliver_insertmanyvalues_batches( 
    2192        self, 
    2193        connection: Connection, 
    2194        cursor: DBAPICursor, 
    2195        statement: str, 
    2196        parameters: _DBAPIMultiExecuteParams, 
    2197        generic_setinputsizes: Optional[_GenericSetInputSizesType], 
    2198        context: ExecutionContext, 
    2199    ) -> Iterator[_InsertManyValuesBatch]: 
    2200        """convert executemany parameters for an INSERT into an iterator 
    2201        of statement/single execute values, used by the insertmanyvalues 
    2202        feature. 
    2203 
    2204        """ 
    2205        raise NotImplementedError() 
    2206 
    2207    def do_executemany( 
    2208        self, 
    2209        cursor: DBAPICursor, 
    2210        statement: str, 
    2211        parameters: _DBAPIMultiExecuteParams, 
    2212        context: Optional[ExecutionContext] = None, 
    2213    ) -> None: 
    2214        """Provide an implementation of ``cursor.executemany(statement, 
    2215        parameters)``.""" 
    2216 
    2217        raise NotImplementedError() 
    2218 
    2219    def do_execute( 
    2220        self, 
    2221        cursor: DBAPICursor, 
    2222        statement: str, 
    2223        parameters: Optional[_DBAPISingleExecuteParams], 
    2224        context: Optional[ExecutionContext] = None, 
    2225    ) -> None: 
    2226        """Provide an implementation of ``cursor.execute(statement, 
    2227        parameters)``.""" 
    2228 
    2229        raise NotImplementedError() 
    2230 
    2231    def do_execute_no_params( 
    2232        self, 
    2233        cursor: DBAPICursor, 
    2234        statement: str, 
    2235        context: Optional[ExecutionContext] = None, 
    2236    ) -> None: 
    2237        """Provide an implementation of ``cursor.execute(statement)``. 
    2238 
    2239        The parameter collection should not be sent. 
    2240 
    2241        """ 
    2242 
    2243        raise NotImplementedError() 
    2244 
    2245    def is_disconnect( 
    2246        self, 
    2247        e: DBAPIModule.Error, 
    2248        connection: Optional[Union[PoolProxiedConnection, DBAPIConnection]], 
    2249        cursor: Optional[DBAPICursor], 
    2250    ) -> bool: 
    2251        """Return True if the given DB-API error indicates an invalid 
    2252        connection""" 
    2253 
    2254        raise NotImplementedError() 
    2255 
    2256    def connect(self, *cargs: Any, **cparams: Any) -> DBAPIConnection: 
    2257        r"""Establish a connection using this dialect's DBAPI. 
    2258 
    2259        The default implementation of this method is:: 
    2260 
    2261            def connect(self, *cargs, **cparams): 
    2262                return self.dbapi.connect(*cargs, **cparams) 
    2263 
    2264        The ``*cargs, **cparams`` parameters are generated directly 
    2265        from this dialect's :meth:`.Dialect.create_connect_args` method. 
    2266 
    2267        This method may be used for dialects that need to perform programmatic 
    2268        per-connection steps when a new connection is procured from the 
    2269        DBAPI. 
    2270 
    2271 
    2272        :param \*cargs: positional parameters returned from the 
    2273         :meth:`.Dialect.create_connect_args` method 
    2274 
    2275        :param \*\*cparams: keyword parameters returned from the 
    2276         :meth:`.Dialect.create_connect_args` method. 
    2277 
    2278        :return: a DBAPI connection, typically from the :pep:`249` module 
    2279         level ``.connect()`` function. 
    2280 
    2281        .. seealso:: 
    2282 
    2283            :meth:`.Dialect.create_connect_args` 
    2284 
    2285            :meth:`.Dialect.on_connect` 
    2286 
    2287        """ 
    2288        raise NotImplementedError() 
    2289 
    2290    def on_connect_url(self, url: URL) -> Optional[Callable[[Any], Any]]: 
    2291        """return a callable which sets up a newly created DBAPI connection. 
    2292 
    2293        This method is a new hook that supersedes the 
    2294        :meth:`_engine.Dialect.on_connect` method when implemented by a 
    2295        dialect.   When not implemented by a dialect, it invokes the 
    2296        :meth:`_engine.Dialect.on_connect` method directly to maintain 
    2297        compatibility with existing dialects.   There is no deprecation 
    2298        for :meth:`_engine.Dialect.on_connect` expected. 
    2299 
    2300        The callable should accept a single argument "conn" which is the 
    2301        DBAPI connection itself.  The inner callable has no 
    2302        return value. 
    2303 
    2304        E.g.:: 
    2305 
    2306            class MyDialect(default.DefaultDialect): 
    2307                # ... 
    2308 
    2309                def on_connect_url(self, url): 
    2310                    def do_on_connect(connection): 
    2311                        connection.execute("SET SPECIAL FLAGS etc") 
    2312 
    2313                    return do_on_connect 
    2314 
    2315        This is used to set dialect-wide per-connection options such as 
    2316        isolation modes, Unicode modes, etc. 
    2317 
    2318        This method differs from :meth:`_engine.Dialect.on_connect` in that 
    2319        it is passed the :class:`_engine.URL` object that's relevant to the 
    2320        connect args.  Normally the only way to get this is from the 
    2321        :meth:`_engine.Dialect.on_connect` hook is to look on the 
    2322        :class:`_engine.Engine` itself, however this URL object may have been 
    2323        replaced by plugins. 
    2324 
    2325        .. note:: 
    2326 
    2327            The default implementation of 
    2328            :meth:`_engine.Dialect.on_connect_url` is to invoke the 
    2329            :meth:`_engine.Dialect.on_connect` method. Therefore if a dialect 
    2330            implements this method, the :meth:`_engine.Dialect.on_connect` 
    2331            method **will not be called** unless the overriding dialect calls 
    2332            it directly from here. 
    2333 
    2334        .. versionadded:: 1.4.3 added :meth:`_engine.Dialect.on_connect_url` 
    2335           which normally calls into :meth:`_engine.Dialect.on_connect`. 
    2336 
    2337        :param url: a :class:`_engine.URL` object representing the 
    2338         :class:`_engine.URL` that was passed to the 
    2339         :meth:`_engine.Dialect.create_connect_args` method. 
    2340 
    2341        :return: a callable that accepts a single DBAPI connection as an 
    2342         argument, or None. 
    2343 
    2344        .. seealso:: 
    2345 
    2346            :meth:`_engine.Dialect.on_connect` 
    2347 
    2348        """ 
    2349        return self.on_connect() 
    2350 
    2351    def on_connect(self) -> Optional[Callable[[Any], None]]: 
    2352        """return a callable which sets up a newly created DBAPI connection. 
    2353 
    2354        The callable should accept a single argument "conn" which is the 
    2355        DBAPI connection itself.  The inner callable has no 
    2356        return value. 
    2357 
    2358        E.g.:: 
    2359 
    2360            class MyDialect(default.DefaultDialect): 
    2361                # ... 
    2362 
    2363                def on_connect(self): 
    2364                    def do_on_connect(connection): 
    2365                        connection.execute("SET SPECIAL FLAGS etc") 
    2366 
    2367                    return do_on_connect 
    2368 
    2369        This is used to set dialect-wide per-connection options such as 
    2370        isolation modes, Unicode modes, etc. 
    2371 
    2372        The "do_on_connect" callable is invoked by using the 
    2373        :meth:`_events.PoolEvents.connect` event 
    2374        hook, then unwrapping the DBAPI connection and passing it into the 
    2375        callable. 
    2376 
    2377        .. versionchanged:: 1.4 the on_connect hook is no longer called twice 
    2378           for the first connection of a dialect.  The on_connect hook is still 
    2379           called before the :meth:`_engine.Dialect.initialize` method however. 
    2380 
    2381        .. versionchanged:: 1.4.3 the on_connect hook is invoked from a new 
    2382           method on_connect_url that passes the URL that was used to create 
    2383           the connect args.   Dialects can implement on_connect_url instead 
    2384           of on_connect if they need the URL object that was used for the 
    2385           connection in order to get additional context. 
    2386 
    2387        If None is returned, no event listener is generated. 
    2388 
    2389        :return: a callable that accepts a single DBAPI connection as an 
    2390         argument, or None. 
    2391 
    2392        .. seealso:: 
    2393 
    2394            :meth:`.Dialect.connect` - allows the DBAPI ``connect()`` sequence 
    2395            itself to be controlled. 
    2396 
    2397            :meth:`.Dialect.on_connect_url` - supersedes 
    2398            :meth:`.Dialect.on_connect` to also receive the 
    2399            :class:`_engine.URL` object in context. 
    2400 
    2401        """ 
    2402        return None 
    2403 
    2404    def reset_isolation_level(self, dbapi_connection: DBAPIConnection) -> None: 
    2405        """Given a DBAPI connection, revert its isolation to the default. 
    2406 
    2407        Note that this is a dialect-level method which is used as part 
    2408        of the implementation of the :class:`_engine.Connection` and 
    2409        :class:`_engine.Engine` 
    2410        isolation level facilities; these APIs should be preferred for 
    2411        most typical use cases. 
    2412 
    2413        .. seealso:: 
    2414 
    2415            :meth:`_engine.Connection.get_isolation_level` 
    2416            - view current level 
    2417 
    2418            :attr:`_engine.Connection.default_isolation_level` 
    2419            - view default level 
    2420 
    2421            :paramref:`.Connection.execution_options.isolation_level` - 
    2422            set per :class:`_engine.Connection` isolation level 
    2423 
    2424            :paramref:`_sa.create_engine.isolation_level` - 
    2425            set per :class:`_engine.Engine` isolation level 
    2426 
    2427        """ 
    2428 
    2429        raise NotImplementedError() 
    2430 
    2431    def set_isolation_level( 
    2432        self, dbapi_connection: DBAPIConnection, level: IsolationLevel 
    2433    ) -> None: 
    2434        """Given a DBAPI connection, set its isolation level. 
    2435 
    2436        Note that this is a dialect-level method which is used as part 
    2437        of the implementation of the :class:`_engine.Connection` and 
    2438        :class:`_engine.Engine` 
    2439        isolation level facilities; these APIs should be preferred for 
    2440        most typical use cases. 
    2441 
    2442        If the dialect also implements the 
    2443        :meth:`.Dialect.get_isolation_level_values` method, then the given 
    2444        level is guaranteed to be one of the string names within that sequence, 
    2445        and the method will not need to anticipate a lookup failure. 
    2446 
    2447        .. seealso:: 
    2448 
    2449            :meth:`_engine.Connection.get_isolation_level` 
    2450            - view current level 
    2451 
    2452            :attr:`_engine.Connection.default_isolation_level` 
    2453            - view default level 
    2454 
    2455            :paramref:`.Connection.execution_options.isolation_level` - 
    2456            set per :class:`_engine.Connection` isolation level 
    2457 
    2458            :paramref:`_sa.create_engine.isolation_level` - 
    2459            set per :class:`_engine.Engine` isolation level 
    2460 
    2461        """ 
    2462 
    2463        raise NotImplementedError() 
    2464 
    2465    def get_isolation_level( 
    2466        self, dbapi_connection: DBAPIConnection 
    2467    ) -> IsolationLevel: 
    2468        """Given a DBAPI connection, return its isolation level. 
    2469 
    2470        When working with a :class:`_engine.Connection` object, 
    2471        the corresponding 
    2472        DBAPI connection may be procured using the 
    2473        :attr:`_engine.Connection.connection` accessor. 
    2474 
    2475        Note that this is a dialect-level method which is used as part 
    2476        of the implementation of the :class:`_engine.Connection` and 
    2477        :class:`_engine.Engine` isolation level facilities; 
    2478        these APIs should be preferred for most typical use cases. 
    2479 
    2480 
    2481        .. seealso:: 
    2482 
    2483            :meth:`_engine.Connection.get_isolation_level` 
    2484            - view current level 
    2485 
    2486            :attr:`_engine.Connection.default_isolation_level` 
    2487            - view default level 
    2488 
    2489            :paramref:`.Connection.execution_options.isolation_level` - 
    2490            set per :class:`_engine.Connection` isolation level 
    2491 
    2492            :paramref:`_sa.create_engine.isolation_level` - 
    2493            set per :class:`_engine.Engine` isolation level 
    2494 
    2495 
    2496        """ 
    2497 
    2498        raise NotImplementedError() 
    2499 
    2500    def detect_autocommit_setting(self, dbapi_conn: DBAPIConnection) -> bool: 
    2501        """Detect the current autocommit setting for a DBAPI connection. 
    2502 
    2503        :param dbapi_connection: a DBAPI connection object 
    2504        :return: True if autocommit is enabled, False if disabled 
    2505        :rtype: bool 
    2506 
    2507        This method inspects the given DBAPI connection to determine 
    2508        whether autocommit mode is currently enabled. The specific 
    2509        mechanism for detecting autocommit varies by database dialect 
    2510        and DBAPI driver, however it should be done **without** network 
    2511        round trips. 
    2512 
    2513        .. note:: 
    2514 
    2515            Not all dialects support autocommit detection. Dialects 
    2516            that do not support this feature will raise 
    2517            :exc:`NotImplementedError`. 
    2518 
    2519        """ 
    2520        raise NotImplementedError( 
    2521            "This dialect cannot detect autocommit on a DBAPI connection" 
    2522        ) 
    2523 
    2524    def get_default_isolation_level( 
    2525        self, dbapi_conn: DBAPIConnection 
    2526    ) -> IsolationLevel: 
    2527        """Given a DBAPI connection, return its isolation level, or 
    2528        a default isolation level if one cannot be retrieved. 
    2529 
    2530        This method may only raise NotImplementedError and 
    2531        **must not raise any other exception**, as it is used implicitly upon 
    2532        first connect. 
    2533 
    2534        The method **must return a value** for a dialect that supports 
    2535        isolation level settings, as this level is what will be reverted 
    2536        towards when a per-connection isolation level change is made. 
    2537 
    2538        The method defaults to using the :meth:`.Dialect.get_isolation_level` 
    2539        method unless overridden by a dialect. 
    2540 
    2541        """ 
    2542        raise NotImplementedError() 
    2543 
    2544    def get_isolation_level_values( 
    2545        self, dbapi_conn: DBAPIConnection 
    2546    ) -> Sequence[IsolationLevel]: 
    2547        """return a sequence of string isolation level names that are accepted 
    2548        by this dialect. 
    2549 
    2550        The available names should use the following conventions: 
    2551 
    2552        * use UPPERCASE names.   isolation level methods will accept lowercase 
    2553          names but these are normalized into UPPERCASE before being passed 
    2554          along to the dialect. 
    2555        * separate words should be separated by spaces, not underscores, e.g. 
    2556          ``REPEATABLE READ``.  isolation level names will have underscores 
    2557          converted to spaces before being passed along to the dialect. 
    2558        * The names for the four standard isolation names to the extent that 
    2559          they are supported by the backend should be ``READ UNCOMMITTED``, 
    2560          ``READ COMMITTED``, ``REPEATABLE READ``, ``SERIALIZABLE`` 
    2561        * if the dialect supports an autocommit option it should be provided 
    2562          using the isolation level name ``AUTOCOMMIT``. 
    2563        * Other isolation modes may also be present, provided that they 
    2564          are named in UPPERCASE and use spaces not underscores. 
    2565 
    2566        This function is used so that the default dialect can check that 
    2567        a given isolation level parameter is valid, else raises an 
    2568        :class:`_exc.ArgumentError`. 
    2569 
    2570        A DBAPI connection is passed to the method, in the unlikely event that 
    2571        the dialect needs to interrogate the connection itself to determine 
    2572        this list, however it is expected that most backends will return 
    2573        a hardcoded list of values.  If the dialect supports "AUTOCOMMIT", 
    2574        that value should also be present in the sequence returned. 
    2575 
    2576        The method raises ``NotImplementedError`` by default.  If a dialect 
    2577        does not implement this method, then the default dialect will not 
    2578        perform any checking on a given isolation level value before passing 
    2579        it onto the :meth:`.Dialect.set_isolation_level` method.  This is 
    2580        to allow backwards-compatibility with third party dialects that may 
    2581        not yet be implementing this method. 
    2582 
    2583        .. versionadded:: 2.0 
    2584 
    2585        """ 
    2586        raise NotImplementedError() 
    2587 
    2588    def _assert_and_set_isolation_level( 
    2589        self, dbapi_conn: DBAPIConnection, level: IsolationLevel 
    2590    ) -> None: 
    2591        raise NotImplementedError() 
    2592 
    2593    @classmethod 
    2594    def get_dialect_cls(cls, url: URL) -> Type[Dialect]: 
    2595        """Given a URL, return the :class:`.Dialect` that will be used. 
    2596 
    2597        This is a hook that allows an external plugin to provide functionality 
    2598        around an existing dialect, by allowing the plugin to be loaded 
    2599        from the url based on an entrypoint, and then the plugin returns 
    2600        the actual dialect to be used. 
    2601 
    2602        By default this just returns the cls. 
    2603 
    2604        """ 
    2605        return cls 
    2606 
    2607    @classmethod 
    2608    def get_async_dialect_cls(cls, url: URL) -> Type[Dialect]: 
    2609        """Given a URL, return the :class:`.Dialect` that will be used by 
    2610        an async engine. 
    2611 
    2612        By default this is an alias of :meth:`.Dialect.get_dialect_cls` and 
    2613        just returns the cls. It may be used if a dialect provides 
    2614        both a sync and async version under the same name, like the 
    2615        ``psycopg`` driver. 
    2616 
    2617        .. versionadded:: 2 
    2618 
    2619        .. seealso:: 
    2620 
    2621            :meth:`.Dialect.get_dialect_cls` 
    2622 
    2623        """ 
    2624        return cls.get_dialect_cls(url) 
    2625 
    2626    @classmethod 
    2627    def load_provisioning(cls) -> None: 
    2628        """set up the provision.py module for this dialect. 
    2629 
    2630        For dialects that include a provision.py module that sets up 
    2631        provisioning followers, this method should initiate that process. 
    2632 
    2633        A typical implementation would be:: 
    2634 
    2635            @classmethod 
    2636            def load_provisioning(cls): 
    2637                __import__("mydialect.provision") 
    2638 
    2639        The default method assumes a module named ``provision.py`` inside 
    2640        the owning package of the current dialect, based on the ``__module__`` 
    2641        attribute:: 
    2642 
    2643            @classmethod 
    2644            def load_provisioning(cls): 
    2645                package = ".".join(cls.__module__.split(".")[0:-1]) 
    2646                try: 
    2647                    __import__(package + ".provision") 
    2648                except ImportError: 
    2649                    pass 
    2650 
    2651        """ 
    2652 
    2653    @classmethod 
    2654    def engine_created(cls, engine: Engine) -> None: 
    2655        """A convenience hook called before returning the final 
    2656        :class:`_engine.Engine`. 
    2657 
    2658        If the dialect returned a different class from the 
    2659        :meth:`.get_dialect_cls` 
    2660        method, then the hook is called on both classes, first on 
    2661        the dialect class returned by the :meth:`.get_dialect_cls` method and 
    2662        then on the class on which the method was called. 
    2663 
    2664        The hook should be used by dialects and/or wrappers to apply special 
    2665        events to the engine or its components.   In particular, it allows 
    2666        a dialect-wrapping class to apply dialect-level events. 
    2667 
    2668        """ 
    2669 
    2670    def get_driver_connection(self, connection: DBAPIConnection) -> Any: 
    2671        """Returns the connection object as returned by the external driver 
    2672        package. 
    2673 
    2674        For normal dialects that use a DBAPI compliant driver this call 
    2675        will just return the ``connection`` passed as argument. 
    2676        For dialects that instead adapt a non DBAPI compliant driver, like 
    2677        when adapting an asyncio driver, this call will return the 
    2678        connection-like object as returned by the driver. 
    2679 
    2680        .. versionadded:: 1.4.24 
    2681 
    2682        """ 
    2683        raise NotImplementedError() 
    2684 
    2685    def set_engine_execution_options( 
    2686        self, engine: Engine, opts: CoreExecuteOptionsParameter 
    2687    ) -> None: 
    2688        """Establish execution options for a given engine. 
    2689 
    2690        This is implemented by :class:`.DefaultDialect` to establish 
    2691        event hooks for new :class:`.Connection` instances created 
    2692        by the given :class:`.Engine` which will then invoke the 
    2693        :meth:`.Dialect.set_connection_execution_options` method for that 
    2694        connection. 
    2695 
    2696        """ 
    2697        raise NotImplementedError() 
    2698 
    2699    def set_connection_execution_options( 
    2700        self, connection: Connection, opts: CoreExecuteOptionsParameter 
    2701    ) -> None: 
    2702        """Establish execution options for a given connection. 
    2703 
    2704        This is implemented by :class:`.DefaultDialect` in order to implement 
    2705        the :paramref:`_engine.Connection.execution_options.isolation_level` 
    2706        execution option.  Dialects can intercept various execution options 
    2707        which may need to modify state on a particular DBAPI connection. 
    2708 
    2709        .. versionadded:: 1.4 
    2710 
    2711        """ 
    2712        raise NotImplementedError() 
    2713 
    2714    def get_dialect_pool_class(self, url: URL) -> Type[Pool]: 
    2715        """return a Pool class to use for a given URL""" 
    2716        raise NotImplementedError() 
    2717 
    2718    def validate_identifier(self, ident: str) -> None: 
    2719        """Validates an identifier name, raising an exception if invalid""" 
    2720 
    2721 
    2722class CreateEnginePlugin: 
    2723    """A set of hooks intended to augment the construction of an 
    2724    :class:`_engine.Engine` object based on entrypoint names in a URL. 
    2725 
    2726    The purpose of :class:`_engine.CreateEnginePlugin` is to allow third-party 
    2727    systems to apply engine, pool and dialect level event listeners without 
    2728    the need for the target application to be modified; instead, the plugin 
    2729    names can be added to the database URL.  Target applications for 
    2730    :class:`_engine.CreateEnginePlugin` include: 
    2731 
    2732    * connection and SQL performance tools, e.g. which use events to track 
    2733      number of checkouts and/or time spent with statements 
    2734 
    2735    * connectivity plugins such as proxies 
    2736 
    2737    A rudimentary :class:`_engine.CreateEnginePlugin` that attaches a logger 
    2738    to an :class:`_engine.Engine` object might look like:: 
    2739 
    2740 
    2741        import logging 
    2742 
    2743        from sqlalchemy.engine import CreateEnginePlugin 
    2744        from sqlalchemy import event 
    2745 
    2746 
    2747        class LogCursorEventsPlugin(CreateEnginePlugin): 
    2748            def __init__(self, url, kwargs): 
    2749                # consume the parameter "log_cursor_logging_name" from the 
    2750                # URL query 
    2751                logging_name = url.query.get( 
    2752                    "log_cursor_logging_name", "log_cursor" 
    2753                ) 
    2754 
    2755                self.log = logging.getLogger(logging_name) 
    2756 
    2757            def update_url(self, url): 
    2758                "update the URL to one that no longer includes our parameters" 
    2759                return url.difference_update_query(["log_cursor_logging_name"]) 
    2760 
    2761            def engine_created(self, engine): 
    2762                "attach an event listener after the new Engine is constructed" 
    2763                event.listen(engine, "before_cursor_execute", self._log_event) 
    2764 
    2765            def _log_event( 
    2766                self, 
    2767                conn, 
    2768                cursor, 
    2769                statement, 
    2770                parameters, 
    2771                context, 
    2772                executemany, 
    2773            ): 
    2774 
    2775                self.log.info("Plugin logged cursor event: %s", statement) 
    2776 
    2777    Plugins are registered using entry points in a similar way as that 
    2778    of dialects:: 
    2779 
    2780        entry_points = { 
    2781            "sqlalchemy.plugins": [ 
    2782                "log_cursor_plugin = myapp.plugins:LogCursorEventsPlugin" 
    2783            ] 
    2784        } 
    2785 
    2786    A plugin that uses the above names would be invoked from a database 
    2787    URL as in:: 
    2788 
    2789        from sqlalchemy import create_engine 
    2790 
    2791        engine = create_engine( 
    2792            "mysql+pymysql://scott:tiger@localhost/test?" 
    2793            "plugin=log_cursor_plugin&log_cursor_logging_name=mylogger" 
    2794        ) 
    2795 
    2796    The ``plugin`` URL parameter supports multiple instances, so that a URL 
    2797    may specify multiple plugins; they are loaded in the order stated 
    2798    in the URL:: 
    2799 
    2800        engine = create_engine( 
    2801            "mysql+pymysql://scott:tiger@localhost/test?" 
    2802            "plugin=plugin_one&plugin=plugin_twp&plugin=plugin_three" 
    2803        ) 
    2804 
    2805    The plugin names may also be passed directly to :func:`_sa.create_engine` 
    2806    using the :paramref:`_sa.create_engine.plugins` argument:: 
    2807 
    2808        engine = create_engine( 
    2809            "mysql+pymysql://scott:tiger@localhost/test", plugins=["myplugin"] 
    2810        ) 
    2811 
    2812    A plugin may consume plugin-specific arguments from the 
    2813    :class:`_engine.URL` object as well as the ``kwargs`` dictionary, which is 
    2814    the dictionary of arguments passed to the :func:`_sa.create_engine` 
    2815    call.  "Consuming" these arguments includes that they must be removed 
    2816    when the plugin initializes, so that the arguments are not passed along 
    2817    to the :class:`_engine.Dialect` constructor, where they will raise an 
    2818    :class:`_exc.ArgumentError` because they are not known by the dialect. 
    2819 
    2820    As of version 1.4 of SQLAlchemy, arguments should continue to be consumed 
    2821    from the ``kwargs`` dictionary directly, by removing the values with a 
    2822    method such as ``dict.pop``. Arguments from the :class:`_engine.URL` object 
    2823    should be consumed by implementing the 
    2824    :meth:`_engine.CreateEnginePlugin.update_url` method, returning a new copy 
    2825    of the :class:`_engine.URL` with plugin-specific parameters removed:: 
    2826 
    2827        class MyPlugin(CreateEnginePlugin): 
    2828            def __init__(self, url, kwargs): 
    2829                self.my_argument_one = url.query["my_argument_one"] 
    2830                self.my_argument_two = url.query["my_argument_two"] 
    2831                self.my_argument_three = kwargs.pop("my_argument_three", None) 
    2832 
    2833            def update_url(self, url): 
    2834                return url.difference_update_query( 
    2835                    ["my_argument_one", "my_argument_two"] 
    2836                ) 
    2837 
    2838    Arguments like those illustrated above would be consumed from a 
    2839    :func:`_sa.create_engine` call such as:: 
    2840 
    2841        from sqlalchemy import create_engine 
    2842 
    2843        engine = create_engine( 
    2844            "mysql+pymysql://scott:tiger@localhost/test?" 
    2845            "plugin=myplugin&my_argument_one=foo&my_argument_two=bar", 
    2846            my_argument_three="bat", 
    2847        ) 
    2848 
    2849    .. versionchanged:: 1.4 
    2850 
    2851        The :class:`_engine.URL` object is now immutable; a 
    2852        :class:`_engine.CreateEnginePlugin` that needs to alter the 
    2853        :class:`_engine.URL` should implement the newly added 
    2854        :meth:`_engine.CreateEnginePlugin.update_url` method, which 
    2855        is invoked after the plugin is constructed. 
    2856 
    2857        For migration, construct the plugin in the following way, checking 
    2858        for the existence of the :meth:`_engine.CreateEnginePlugin.update_url` 
    2859        method to detect which version is running:: 
    2860 
    2861            class MyPlugin(CreateEnginePlugin): 
    2862                def __init__(self, url, kwargs): 
    2863                    if hasattr(CreateEnginePlugin, "update_url"): 
    2864                        # detect the 1.4 API 
    2865                        self.my_argument_one = url.query["my_argument_one"] 
    2866                        self.my_argument_two = url.query["my_argument_two"] 
    2867                    else: 
    2868                        # detect the 1.3 and earlier API - mutate the 
    2869                        # URL directly 
    2870                        self.my_argument_one = url.query.pop("my_argument_one") 
    2871                        self.my_argument_two = url.query.pop("my_argument_two") 
    2872 
    2873                    self.my_argument_three = kwargs.pop("my_argument_three", None) 
    2874 
    2875                def update_url(self, url): 
    2876                    # this method is only called in the 1.4 version 
    2877                    return url.difference_update_query( 
    2878                        ["my_argument_one", "my_argument_two"] 
    2879                    ) 
    2880 
    2881        .. seealso:: 
    2882 
    2883            :ref:`change_5526` - overview of the :class:`_engine.URL` change which 
    2884            also includes notes regarding :class:`_engine.CreateEnginePlugin`. 
    2885 
    2886 
    2887    When the engine creation process completes and produces the 
    2888    :class:`_engine.Engine` object, it is again passed to the plugin via the 
    2889    :meth:`_engine.CreateEnginePlugin.engine_created` hook.  In this hook, additional 
    2890    changes can be made to the engine, most typically involving setup of 
    2891    events (e.g. those defined in :ref:`core_event_toplevel`). 
    2892 
    2893    """  # noqa: E501 
    2894 
    2895    def __init__(self, url: URL, kwargs: Dict[str, Any]): 
    2896        """Construct a new :class:`.CreateEnginePlugin`. 
    2897 
    2898        The plugin object is instantiated individually for each call 
    2899        to :func:`_sa.create_engine`.  A single :class:`_engine. 
    2900        Engine` will be 
    2901        passed to the :meth:`.CreateEnginePlugin.engine_created` method 
    2902        corresponding to this URL. 
    2903 
    2904        :param url: the :class:`_engine.URL` object.  The plugin may inspect 
    2905         the :class:`_engine.URL` for arguments.  Arguments used by the 
    2906         plugin should be removed, by returning an updated :class:`_engine.URL` 
    2907         from the :meth:`_engine.CreateEnginePlugin.update_url` method. 
    2908 
    2909         .. versionchanged::  1.4 
    2910 
    2911            The :class:`_engine.URL` object is now immutable, so a 
    2912            :class:`_engine.CreateEnginePlugin` that needs to alter the 
    2913            :class:`_engine.URL` object should implement the 
    2914            :meth:`_engine.CreateEnginePlugin.update_url` method. 
    2915 
    2916        :param kwargs: The keyword arguments passed to 
    2917         :func:`_sa.create_engine`. 
    2918 
    2919        """ 
    2920        self.url = url 
    2921 
    2922    def update_url(self, url: URL) -> URL: 
    2923        """Update the :class:`_engine.URL`. 
    2924 
    2925        A new :class:`_engine.URL` should be returned.   This method is 
    2926        typically used to consume configuration arguments from the 
    2927        :class:`_engine.URL` which must be removed, as they will not be 
    2928        recognized by the dialect.  The 
    2929        :meth:`_engine.URL.difference_update_query` method is available 
    2930        to remove these arguments.   See the docstring at 
    2931        :class:`_engine.CreateEnginePlugin` for an example. 
    2932 
    2933 
    2934        .. versionadded:: 1.4 
    2935 
    2936        """ 
    2937        raise NotImplementedError() 
    2938 
    2939    def handle_dialect_kwargs( 
    2940        self, dialect_cls: Type[Dialect], dialect_args: Dict[str, Any] 
    2941    ) -> None: 
    2942        """parse and modify dialect kwargs""" 
    2943 
    2944    def handle_pool_kwargs( 
    2945        self, pool_cls: Type[Pool], pool_args: Dict[str, Any] 
    2946    ) -> None: 
    2947        """parse and modify pool kwargs""" 
    2948 
    2949    def engine_created(self, engine: Engine) -> None: 
    2950        """Receive the :class:`_engine.Engine` 
    2951        object when it is fully constructed. 
    2952 
    2953        The plugin may make additional changes to the engine, such as 
    2954        registering engine or connection pool events. 
    2955 
    2956        """ 
    2957 
    2958 
    2959class ExecutionContext: 
    2960    """A messenger object for a Dialect that corresponds to a single 
    2961    execution. 
    2962 
    2963    """ 
    2964 
    2965    engine: Engine 
    2966    """engine which the Connection is associated with""" 
    2967 
    2968    connection: Connection 
    2969    """Connection object which can be freely used by default value 
    2970      generators to execute SQL.  This Connection should reference the 
    2971      same underlying connection/transactional resources of 
    2972      root_connection.""" 
    2973 
    2974    root_connection: Connection 
    2975    """Connection object which is the source of this ExecutionContext.""" 
    2976 
    2977    dialect: Dialect 
    2978    """dialect which created this ExecutionContext.""" 
    2979 
    2980    cursor: DBAPICursor 
    2981    """DB-API cursor procured from the connection""" 
    2982 
    2983    compiled: Optional[Compiled] 
    2984    """if passed to constructor, sqlalchemy.engine.base.Compiled object 
    2985      being executed""" 
    2986 
    2987    statement: str 
    2988    """string version of the statement to be executed.  Is either 
    2989      passed to the constructor, or must be created from the 
    2990      sql.Compiled object by the time pre_exec() has completed.""" 
    2991 
    2992    invoked_statement: Optional[Executable] 
    2993    """The Executable statement object that was given in the first place. 
    2994 
    2995    This should be structurally equivalent to compiled.statement, but not 
    2996    necessarily the same object as in a caching scenario the compiled form 
    2997    will have been extracted from the cache. 
    2998 
    2999    """ 
    3000 
    3001    parameters: _AnyMultiExecuteParams 
    3002    """bind parameters passed to the execute() or exec_driver_sql() methods. 
    3003 
    3004    These are always stored as a list of parameter entries.  A single-element 
    3005    list corresponds to a ``cursor.execute()`` call and a multiple-element 
    3006    list corresponds to ``cursor.executemany()``, except in the case 
    3007    of :attr:`.ExecuteStyle.INSERTMANYVALUES` which will use 
    3008    ``cursor.execute()`` one or more times. 
    3009 
    3010    """ 
    3011 
    3012    no_parameters: bool 
    3013    """True if the execution style does not use parameters""" 
    3014 
    3015    isinsert: bool 
    3016    """True if the statement is an INSERT.""" 
    3017 
    3018    isupdate: bool 
    3019    """True if the statement is an UPDATE.""" 
    3020 
    3021    execute_style: ExecuteStyle 
    3022    """the style of DBAPI cursor method that will be used to execute 
    3023    a statement. 
    3024 
    3025    .. versionadded:: 2.0 
    3026 
    3027    """ 
    3028 
    3029    executemany: bool 
    3030    """True if the context has a list of more than one parameter set. 
    3031 
    3032    Historically this attribute links to whether ``cursor.execute()`` or 
    3033    ``cursor.executemany()`` will be used.  It also can now mean that 
    3034    "insertmanyvalues" may be used which indicates one or more 
    3035    ``cursor.execute()`` calls. 
    3036 
    3037    """ 
    3038 
    3039    prefetch_cols: util.generic_fn_descriptor[Optional[Sequence[Column[Any]]]] 
    3040    """a list of Column objects for which a client-side default 
    3041      was fired off.  Applies to inserts and updates.""" 
    3042 
    3043    postfetch_cols: util.generic_fn_descriptor[Optional[Sequence[Column[Any]]]] 
    3044    """a list of Column objects for which a server-side default or 
    3045      inline SQL expression value was fired off.  Applies to inserts 
    3046      and updates.""" 
    3047 
    3048    execution_options: _ExecuteOptions 
    3049    """Execution options associated with the current statement execution""" 
    3050 
    3051    @classmethod 
    3052    def _init_ddl( 
    3053        cls, 
    3054        dialect: Dialect, 
    3055        connection: Connection, 
    3056        dbapi_connection: PoolProxiedConnection, 
    3057        execution_options: _ExecuteOptions, 
    3058        compiled_ddl: DDLCompiler, 
    3059    ) -> ExecutionContext: 
    3060        raise NotImplementedError() 
    3061 
    3062    @classmethod 
    3063    def _init_compiled( 
    3064        cls, 
    3065        dialect: Dialect, 
    3066        connection: Connection, 
    3067        dbapi_connection: PoolProxiedConnection, 
    3068        execution_options: _ExecuteOptions, 
    3069        compiled: SQLCompiler, 
    3070        parameters: _CoreMultiExecuteParams, 
    3071        invoked_statement: Executable, 
    3072        extracted_parameters: Optional[Sequence[BindParameter[Any]]], 
    3073        cache_hit: CacheStats = CacheStats.CACHING_DISABLED, 
    3074    ) -> ExecutionContext: 
    3075        raise NotImplementedError() 
    3076 
    3077    @classmethod 
    3078    def _init_statement( 
    3079        cls, 
    3080        dialect: Dialect, 
    3081        connection: Connection, 
    3082        dbapi_connection: PoolProxiedConnection, 
    3083        execution_options: _ExecuteOptions, 
    3084        statement: str, 
    3085        parameters: _DBAPIMultiExecuteParams, 
    3086    ) -> ExecutionContext: 
    3087        raise NotImplementedError() 
    3088 
    3089    @classmethod 
    3090    def _init_default( 
    3091        cls, 
    3092        dialect: Dialect, 
    3093        connection: Connection, 
    3094        dbapi_connection: PoolProxiedConnection, 
    3095        execution_options: _ExecuteOptions, 
    3096    ) -> ExecutionContext: 
    3097        raise NotImplementedError() 
    3098 
    3099    def _exec_default( 
    3100        self, 
    3101        column: Optional[Column[Any]], 
    3102        default: DefaultGenerator, 
    3103        type_: Optional[TypeEngine[Any]], 
    3104    ) -> Any: 
    3105        raise NotImplementedError() 
    3106 
    3107    def _prepare_set_input_sizes( 
    3108        self, 
    3109    ) -> Optional[List[Tuple[str, Any, TypeEngine[Any]]]]: 
    3110        raise NotImplementedError() 
    3111 
    3112    def _get_cache_stats(self) -> str: 
    3113        raise NotImplementedError() 
    3114 
    3115    def _setup_result_proxy(self) -> CursorResult[Any]: 
    3116        raise NotImplementedError() 
    3117 
    3118    def fire_sequence(self, seq: Sequence_SchemaItem, type_: Integer) -> int: 
    3119        """given a :class:`.Sequence`, invoke it and return the next int 
    3120        value""" 
    3121        raise NotImplementedError() 
    3122 
    3123    def create_cursor(self) -> DBAPICursor: 
    3124        """Return a new cursor generated from this ExecutionContext's 
    3125        connection. 
    3126 
    3127        Some dialects may wish to change the behavior of 
    3128        connection.cursor(), such as postgresql which may return a PG 
    3129        "server side" cursor. 
    3130        """ 
    3131 
    3132        raise NotImplementedError() 
    3133 
    3134    def pre_exec(self) -> None: 
    3135        """Called before an execution of a compiled statement. 
    3136 
    3137        If a compiled statement was passed to this ExecutionContext, 
    3138        the `statement` and `parameters` datamembers must be 
    3139        initialized after this statement is complete. 
    3140        """ 
    3141 
    3142        raise NotImplementedError() 
    3143 
    3144    def get_out_parameter_values( 
    3145        self, out_param_names: Sequence[str] 
    3146    ) -> Sequence[Any]: 
    3147        """Return a sequence of OUT parameter values from a cursor. 
    3148 
    3149        For dialects that support OUT parameters, this method will be called 
    3150        when there is a :class:`.SQLCompiler` object which has the 
    3151        :attr:`.SQLCompiler.has_out_parameters` flag set.  This flag in turn 
    3152        will be set to True if the statement itself has :class:`.BindParameter` 
    3153        objects that have the ``.isoutparam`` flag set which are consumed by 
    3154        the :meth:`.SQLCompiler.visit_bindparam` method.  If the dialect 
    3155        compiler produces :class:`.BindParameter` objects with ``.isoutparam`` 
    3156        set which are not handled by :meth:`.SQLCompiler.visit_bindparam`, it 
    3157        should set this flag explicitly. 
    3158 
    3159        The list of names that were rendered for each bound parameter 
    3160        is passed to the method.  The method should then return a sequence of 
    3161        values corresponding to the list of parameter objects. Unlike in 
    3162        previous SQLAlchemy versions, the values can be the **raw values** from 
    3163        the DBAPI; the execution context will apply the appropriate type 
    3164        handler based on what's present in self.compiled.binds and update the 
    3165        values.  The processed dictionary will then be made available via the 
    3166        ``.out_parameters`` collection on the result object.  Note that 
    3167        SQLAlchemy 1.4 has multiple kinds of result object as part of the 2.0 
    3168        transition. 
    3169 
    3170        .. versionadded:: 1.4 - added 
    3171           :meth:`.ExecutionContext.get_out_parameter_values`, which is invoked 
    3172           automatically by the :class:`.DefaultExecutionContext` when there 
    3173           are :class:`.BindParameter` objects with the ``.isoutparam`` flag 
    3174           set.  This replaces the practice of setting out parameters within 
    3175           the now-removed ``get_result_proxy()`` method. 
    3176 
    3177        """ 
    3178        raise NotImplementedError() 
    3179 
    3180    def post_exec(self) -> None: 
    3181        """Called after the execution of a compiled statement. 
    3182 
    3183        If a compiled statement was passed to this ExecutionContext, 
    3184        the `last_insert_ids`, `last_inserted_params`, etc. 
    3185        datamembers should be available after this method completes. 
    3186        """ 
    3187 
    3188        raise NotImplementedError() 
    3189 
    3190    def handle_dbapi_exception(self, e: BaseException) -> None: 
    3191        """Receive a DBAPI exception which occurred upon execute, result 
    3192        fetch, etc.""" 
    3193 
    3194        raise NotImplementedError() 
    3195 
    3196    def lastrow_has_defaults(self) -> bool: 
    3197        """Return True if the last INSERT or UPDATE row contained 
    3198        inlined or database-side defaults. 
    3199        """ 
    3200 
    3201        raise NotImplementedError() 
    3202 
    3203    def get_rowcount(self) -> Optional[int]: 
    3204        """Return the DBAPI ``cursor.rowcount`` value, or in some 
    3205        cases an interpreted value. 
    3206 
    3207        See :attr:`_engine.CursorResult.rowcount` for details on this. 
    3208 
    3209        """ 
    3210 
    3211        raise NotImplementedError() 
    3212 
    3213    def fetchall_for_returning(self, cursor: DBAPICursor) -> Sequence[Any]: 
    3214        """For a RETURNING result, deliver cursor.fetchall() from the 
    3215        DBAPI cursor. 
    3216 
    3217        This is a dialect-specific hook for dialects that have special 
    3218        considerations when calling upon the rows delivered for a 
    3219        "RETURNING" statement.   Default implementation is 
    3220        ``cursor.fetchall()``. 
    3221 
    3222        This hook is currently used only by the :term:`insertmanyvalues` 
    3223        feature.   Dialects that don't set ``use_insertmanyvalues=True`` 
    3224        don't need to consider this hook. 
    3225 
    3226        .. versionadded:: 2.0.10 
    3227 
    3228        """ 
    3229        raise NotImplementedError() 
    3230 
    3231 
    3232class ConnectionEventsTarget(EventTarget): 
    3233    """An object which can accept events from :class:`.ConnectionEvents`. 
    3234 
    3235    Includes :class:`_engine.Connection` and :class:`_engine.Engine`. 
    3236 
    3237    .. versionadded:: 2.0 
    3238 
    3239    """ 
    3240 
    3241    dispatch: dispatcher[ConnectionEventsTarget] 
    3242 
    3243 
    3244Connectable = ConnectionEventsTarget 
    3245 
    3246 
    3247class ExceptionContext: 
    3248    """Encapsulate information about an error condition in progress. 
    3249 
    3250    This object exists solely to be passed to the 
    3251    :meth:`_events.DialectEvents.handle_error` event, 
    3252    supporting an interface that 
    3253    can be extended without backwards-incompatibility. 
    3254 
    3255 
    3256    """ 
    3257 
    3258    __slots__ = () 
    3259 
    3260    dialect: Dialect 
    3261    """The :class:`_engine.Dialect` in use. 
    3262 
    3263    This member is present for all invocations of the event hook. 
    3264 
    3265    .. versionadded:: 2.0 
    3266 
    3267    """ 
    3268 
    3269    connection: Optional[Connection] 
    3270    """The :class:`_engine.Connection` in use during the exception. 
    3271 
    3272    This member is present, except in the case of a failure when 
    3273    first connecting. 
    3274 
    3275    .. seealso:: 
    3276 
    3277        :attr:`.ExceptionContext.engine` 
    3278 
    3279 
    3280    """ 
    3281 
    3282    engine: Optional[Engine] 
    3283    """The :class:`_engine.Engine` in use during the exception. 
    3284 
    3285    This member is present in all cases except for when handling an error 
    3286    within the connection pool "pre-ping" process. 
    3287 
    3288    """ 
    3289 
    3290    cursor: Optional[DBAPICursor] 
    3291    """The DBAPI cursor object. 
    3292 
    3293    May be None. 
    3294 
    3295    """ 
    3296 
    3297    statement: Optional[str] 
    3298    """String SQL statement that was emitted directly to the DBAPI. 
    3299 
    3300    May be None. 
    3301 
    3302    """ 
    3303 
    3304    parameters: Optional[_DBAPIAnyExecuteParams] 
    3305    """Parameter collection that was emitted directly to the DBAPI. 
    3306 
    3307    May be None. 
    3308 
    3309    """ 
    3310 
    3311    original_exception: BaseException 
    3312    """The exception object which was caught. 
    3313 
    3314    This member is always present. 
    3315 
    3316    """ 
    3317 
    3318    sqlalchemy_exception: Optional[StatementError] 
    3319    """The :class:`sqlalchemy.exc.StatementError` which wraps the original, 
    3320    and will be raised if exception handling is not circumvented by the event. 
    3321 
    3322    May be None, as not all exception types are wrapped by SQLAlchemy. 
    3323    For DBAPI-level exceptions that subclass the dbapi's Error class, this 
    3324    field will always be present. 
    3325 
    3326    """ 
    3327 
    3328    chained_exception: Optional[BaseException] 
    3329    """The exception that was returned by the previous handler in the 
    3330    exception chain, if any. 
    3331 
    3332    If present, this exception will be the one ultimately raised by 
    3333    SQLAlchemy unless a subsequent handler replaces it. 
    3334 
    3335    May be None. 
    3336 
    3337    """ 
    3338 
    3339    execution_context: Optional[ExecutionContext] 
    3340    """The :class:`.ExecutionContext` corresponding to the execution 
    3341    operation in progress. 
    3342 
    3343    This is present for statement execution operations, but not for 
    3344    operations such as transaction begin/end.  It also is not present when 
    3345    the exception was raised before the :class:`.ExecutionContext` 
    3346    could be constructed. 
    3347 
    3348    Note that the :attr:`.ExceptionContext.statement` and 
    3349    :attr:`.ExceptionContext.parameters` members may represent a 
    3350    different value than that of the :class:`.ExecutionContext`, 
    3351    potentially in the case where a 
    3352    :meth:`_events.ConnectionEvents.before_cursor_execute` event or similar 
    3353    modified the statement/parameters to be sent. 
    3354 
    3355    May be None. 
    3356 
    3357    """ 
    3358 
    3359    is_disconnect: bool 
    3360    """Represent whether the exception as occurred represents a "disconnect" 
    3361    condition. 
    3362 
    3363    This flag will always be True or False within the scope of the 
    3364    :meth:`_events.DialectEvents.handle_error` handler. 
    3365 
    3366    SQLAlchemy will defer to this flag in order to determine whether or not 
    3367    the connection should be invalidated subsequently.    That is, by 
    3368    assigning to this flag, a "disconnect" event which then results in 
    3369    a connection and pool invalidation can be invoked or prevented by 
    3370    changing this flag. 
    3371 
    3372 
    3373    .. note:: The pool "pre_ping" handler enabled using the 
    3374        :paramref:`_sa.create_engine.pool_pre_ping` parameter does **not** 
    3375        consult this event before deciding if the "ping" returned false, 
    3376        as opposed to receiving an unhandled error.   For this use case, the 
    3377        :ref:`legacy recipe based on engine_connect() may be used 
    3378        <pool_disconnects_pessimistic_custom>`.  A future API allow more 
    3379        comprehensive customization of the "disconnect" detection mechanism 
    3380        across all functions. 
    3381 
    3382    """ 
    3383 
    3384    invalidate_pool_on_disconnect: bool 
    3385    """Represent whether all connections in the pool should be invalidated 
    3386    when a "disconnect" condition is in effect. 
    3387 
    3388    Setting this flag to False within the scope of the 
    3389    :meth:`_events.DialectEvents.handle_error` 
    3390    event will have the effect such 
    3391    that the full collection of connections in the pool will not be 
    3392    invalidated during a disconnect; only the current connection that is the 
    3393    subject of the error will actually be invalidated. 
    3394 
    3395    The purpose of this flag is for custom disconnect-handling schemes where 
    3396    the invalidation of other connections in the pool is to be performed 
    3397    based on other conditions, or even on a per-connection basis. 
    3398 
    3399    """ 
    3400 
    3401    is_pre_ping: bool 
    3402    """Indicates if this error is occurring within the "pre-ping" step 
    3403    performed when :paramref:`_sa.create_engine.pool_pre_ping` is set to 
    3404    ``True``.  In this mode, the :attr:`.ExceptionContext.engine` attribute 
    3405    will be ``None``.  The dialect in use is accessible via the 
    3406    :attr:`.ExceptionContext.dialect` attribute. 
    3407 
    3408    .. versionadded:: 2.0.5 
    3409 
    3410    """ 
    3411 
    3412 
    3413class AdaptedConnection: 
    3414    """Interface of an adapted connection object to support the DBAPI protocol. 
    3415 
    3416    Used by asyncio dialects to provide a sync-style pep-249 facade on top 
    3417    of the asyncio connection/cursor API provided by the driver. 
    3418 
    3419    .. versionadded:: 1.4.24 
    3420 
    3421    """ 
    3422 
    3423    __slots__ = ("_connection",) 
    3424 
    3425    _connection: AsyncIODBAPIConnection 
    3426 
    3427    @property 
    3428    def driver_connection(self) -> Any: 
    3429        """The connection object as returned by the driver after a connect.""" 
    3430        return self._connection 
    3431 
    3432    def run_async(self, fn: Callable[[Any], Awaitable[_T]]) -> _T: 
    3433        """Run the awaitable returned by the given function, which is passed 
    3434        the raw asyncio driver connection. 
    3435 
    3436        This is used to invoke awaitable-only methods on the driver connection 
    3437        within the context of a "synchronous" method, like a connection 
    3438        pool event handler. 
    3439 
    3440        E.g.:: 
    3441 
    3442            engine = create_async_engine(...) 
    3443 
    3444 
    3445            @event.listens_for(engine.sync_engine, "connect") 
    3446            def register_custom_types( 
    3447                dbapi_connection,  # ... 
    3448            ): 
    3449                dbapi_connection.run_async( 
    3450                    lambda connection: connection.set_type_codec( 
    3451                        "MyCustomType", encoder, decoder, ... 
    3452                    ) 
    3453                ) 
    3454 
    3455        .. versionadded:: 1.4.30 
    3456 
    3457        .. seealso:: 
    3458 
    3459            :ref:`asyncio_events_run_async` 
    3460 
    3461        """ 
    3462        return await_(fn(self._connection)) 
    3463 
    3464    def __repr__(self) -> str: 
    3465        return "<AdaptedConnection %s>" % self._connection