summaryrefslogtreecommitdiffstats
path: root/lib/sqlalchemy/engine/interfaces.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqlalchemy/engine/interfaces.py')
-rw-r--r--lib/sqlalchemy/engine/interfaces.py1719
1 files changed, 1719 insertions, 0 deletions
diff --git a/lib/sqlalchemy/engine/interfaces.py b/lib/sqlalchemy/engine/interfaces.py
new file mode 100644
index 0000000..4f2524a
--- /dev/null
+++ b/lib/sqlalchemy/engine/interfaces.py
@@ -0,0 +1,1719 @@
+# engine/interfaces.py
+# Copyright (C) 2005-2022 the SQLAlchemy authors and contributors
+# <see AUTHORS file>
+#
+# This module is part of SQLAlchemy and is released under
+# the MIT License: https://www.opensource.org/licenses/mit-license.php
+
+"""Define core interfaces used by the engine system."""
+
+from .. import util
+from ..sql.compiler import Compiled # noqa
+from ..sql.compiler import TypeCompiler # noqa
+from ..util.concurrency import await_only
+
+
+class Dialect(object):
+ """Define the behavior of a specific database and DB-API combination.
+
+ Any aspect of metadata definition, SQL query generation,
+ execution, result-set handling, or anything else which varies
+ between databases is defined under the general category of the
+ Dialect. The Dialect acts as a factory for other
+ database-specific object implementations including
+ ExecutionContext, Compiled, DefaultGenerator, and TypeEngine.
+
+ .. note:: Third party dialects should not subclass :class:`.Dialect`
+ directly. Instead, subclass :class:`.default.DefaultDialect` or
+ descendant class.
+
+ All dialects include the following attributes. There are many other
+ attributes that may be supported as well:
+
+ ``name``
+ identifying name for the dialect from a DBAPI-neutral point of view
+ (i.e. 'sqlite')
+
+ ``driver``
+ identifying name for the dialect's DBAPI
+
+ ``positional``
+ True if the paramstyle for this Dialect is positional.
+
+ ``paramstyle``
+ the paramstyle to be used (some DB-APIs support multiple
+ paramstyles).
+
+ ``encoding``
+ type of encoding to use for unicode, usually defaults to
+ 'utf-8'.
+
+ ``statement_compiler``
+ a :class:`.Compiled` class used to compile SQL statements
+
+ ``ddl_compiler``
+ a :class:`.Compiled` class used to compile DDL statements
+
+ ``server_version_info``
+ a tuple containing a version number for the DB backend in use.
+ This value is only available for supporting dialects, and is
+ typically populated during the initial connection to the database.
+
+ ``default_schema_name``
+ the name of the default schema. This value is only available for
+ supporting dialects, and is typically populated during the
+ initial connection to the database.
+
+ ``execution_ctx_cls``
+ a :class:`.ExecutionContext` class used to handle statement execution
+
+ ``execute_sequence_format``
+ either the 'tuple' or 'list' type, depending on what cursor.execute()
+ accepts for the second argument (they vary).
+
+ ``preparer``
+ a :class:`~sqlalchemy.sql.compiler.IdentifierPreparer` class used to
+ quote identifiers.
+
+ ``supports_alter``
+ ``True`` if the database supports ``ALTER TABLE`` - used only for
+ generating foreign key constraints in certain circumstances
+
+ ``max_identifier_length``
+ The maximum length of identifier names.
+
+ ``supports_sane_rowcount``
+ Indicate whether the dialect properly implements rowcount for
+ ``UPDATE`` and ``DELETE`` statements.
+
+ ``supports_sane_multi_rowcount``
+ Indicate whether the dialect properly implements rowcount for
+ ``UPDATE`` and ``DELETE`` statements when executed via
+ executemany.
+
+ ``preexecute_autoincrement_sequences``
+ True if 'implicit' primary key functions must be executed separately
+ in order to get their value. This is currently oriented towards
+ PostgreSQL.
+
+ ``implicit_returning``
+ use RETURNING or equivalent during INSERT execution in order to load
+ newly generated primary keys and other column defaults in one execution,
+ which are then available via inserted_primary_key.
+ If an insert statement has returning() specified explicitly,
+ the "implicit" functionality is not used and inserted_primary_key
+ will not be available.
+
+ ``colspecs``
+ A dictionary of TypeEngine classes from sqlalchemy.types mapped
+ to subclasses that are specific to the dialect class. This
+ dictionary is class-level only and is not accessed from the
+ dialect instance itself.
+
+ ``supports_default_values``
+ Indicates if the construct ``INSERT INTO tablename DEFAULT
+ VALUES`` is supported
+
+ ``supports_sequences``
+ Indicates if the dialect supports CREATE SEQUENCE or similar.
+
+ ``sequences_optional``
+ If True, indicates if the "optional" flag on the Sequence() construct
+ should signal to not generate a CREATE SEQUENCE. Applies only to
+ dialects that support sequences. Currently used only to allow PostgreSQL
+ SERIAL to be used on a column that specifies Sequence() for usage on
+ other backends.
+
+ ``supports_native_enum``
+ Indicates if the dialect supports a native ENUM construct.
+ This will prevent types.Enum from generating a CHECK
+ constraint when that type is used.
+
+ ``supports_native_boolean``
+ Indicates if the dialect supports a native boolean construct.
+ This will prevent types.Boolean from generating a CHECK
+ constraint when that type is used.
+
+ ``dbapi_exception_translation_map``
+ A dictionary of names that will contain as values the names of
+ pep-249 exceptions ("IntegrityError", "OperationalError", etc)
+ keyed to alternate class names, to support the case where a
+ DBAPI has exception classes that aren't named as they are
+ referred to (e.g. IntegrityError = MyException). In the vast
+ majority of cases this dictionary is empty.
+
+ .. versionadded:: 1.0.5
+
+ """
+
+ _has_events = False
+
+ supports_statement_cache = True
+ """indicates if this dialect supports caching.
+
+ All dialects that are compatible with statement caching should set this
+ flag to True directly on each dialect class and subclass that supports
+ it. SQLAlchemy tests that this flag is locally present on each dialect
+ subclass before it will use statement caching. This is to provide
+ safety for legacy or new dialects that are not yet fully tested to be
+ compliant with SQL statement caching.
+
+ .. versionadded:: 1.4.5
+
+ .. seealso::
+
+ :ref:`engine_thirdparty_caching`
+
+ """
+
+ def create_connect_args(self, url):
+ """Build DB-API compatible connection arguments.
+
+ Given a :class:`.URL` object, returns a tuple
+ consisting of a ``(*args, **kwargs)`` suitable to send directly
+ to the dbapi's connect function. The arguments are sent to the
+ :meth:`.Dialect.connect` method which then runs the DBAPI-level
+ ``connect()`` function.
+
+ The method typically makes use of the
+ :meth:`.URL.translate_connect_args`
+ method in order to generate a dictionary of options.
+
+ The default implementation is::
+
+ def create_connect_args(self, url):
+ opts = url.translate_connect_args()
+ opts.update(url.query)
+ return [[], opts]
+
+ :param url: a :class:`.URL` object
+
+ :return: a tuple of ``(*args, **kwargs)`` which will be passed to the
+ :meth:`.Dialect.connect` method.
+
+ .. seealso::
+
+ :meth:`.URL.translate_connect_args`
+
+ """
+
+ raise NotImplementedError()
+
+ @classmethod
+ def type_descriptor(cls, typeobj):
+ """Transform a generic type to a dialect-specific type.
+
+ Dialect classes will usually use the
+ :func:`_types.adapt_type` function in the types module to
+ accomplish this.
+
+ The returned result is cached *per dialect class* so can
+ contain no dialect-instance state.
+
+ """
+
+ raise NotImplementedError()
+
+ def initialize(self, connection):
+ """Called during strategized creation of the dialect with a
+ connection.
+
+ Allows dialects to configure options based on server version info or
+ other properties.
+
+ The connection passed here is a SQLAlchemy Connection object,
+ with full capabilities.
+
+ The initialize() method of the base dialect should be called via
+ super().
+
+ .. note:: as of SQLAlchemy 1.4, this method is called **before**
+ any :meth:`_engine.Dialect.on_connect` hooks are called.
+
+ """
+
+ pass
+
+ def get_columns(self, connection, table_name, schema=None, **kw):
+ """Return information about columns in `table_name`.
+
+ Given a :class:`_engine.Connection`, a string
+ `table_name`, and an optional string `schema`, return column
+ information as a list of dictionaries with these keys:
+
+ name
+ the column's name
+
+ type
+ [sqlalchemy.types#TypeEngine]
+
+ nullable
+ boolean
+
+ default
+ the column's default value
+
+ autoincrement
+ boolean
+
+ sequence
+ a dictionary of the form
+ {'name' : str, 'start' :int, 'increment': int, 'minvalue': int,
+ 'maxvalue': int, 'nominvalue': bool, 'nomaxvalue': bool,
+ 'cycle': bool, 'cache': int, 'order': bool}
+
+ Additional column attributes may be present.
+ """
+
+ raise NotImplementedError()
+
+ def get_pk_constraint(self, connection, table_name, schema=None, **kw):
+ """Return information about the primary key constraint on
+ table_name`.
+
+ Given a :class:`_engine.Connection`, a string
+ `table_name`, and an optional string `schema`, return primary
+ key information as a dictionary with these keys:
+
+ constrained_columns
+ a list of column names that make up the primary key
+
+ name
+ optional name of the primary key constraint.
+
+ """
+ raise NotImplementedError()
+
+ def get_foreign_keys(self, connection, table_name, schema=None, **kw):
+ """Return information about foreign_keys in `table_name`.
+
+ Given a :class:`_engine.Connection`, a string
+ `table_name`, and an optional string `schema`, return foreign
+ key information as a list of dicts with these keys:
+
+ name
+ the constraint's name
+
+ constrained_columns
+ a list of column names that make up the foreign key
+
+ referred_schema
+ the name of the referred schema
+
+ referred_table
+ the name of the referred table
+
+ referred_columns
+ a list of column names in the referred table that correspond to
+ constrained_columns
+ """
+
+ raise NotImplementedError()
+
+ def get_table_names(self, connection, schema=None, **kw):
+ """Return a list of table names for `schema`."""
+
+ raise NotImplementedError()
+
+ def get_temp_table_names(self, connection, schema=None, **kw):
+ """Return a list of temporary table names on the given connection,
+ if supported by the underlying backend.
+
+ """
+
+ raise NotImplementedError()
+
+ def get_view_names(self, connection, schema=None, **kw):
+ """Return a list of all view names available in the database.
+
+ :param schema: schema name to query, if not the default schema.
+ """
+
+ raise NotImplementedError()
+
+ def get_sequence_names(self, connection, schema=None, **kw):
+ """Return a list of all sequence names available in the database.
+
+ :param schema: schema name to query, if not the default schema.
+
+ .. versionadded:: 1.4
+ """
+
+ raise NotImplementedError()
+
+ def get_temp_view_names(self, connection, schema=None, **kw):
+ """Return a list of temporary view names on the given connection,
+ if supported by the underlying backend.
+
+ """
+
+ raise NotImplementedError()
+
+ def get_view_definition(self, connection, view_name, schema=None, **kw):
+ """Return view definition.
+
+ Given a :class:`_engine.Connection`, a string
+ `view_name`, and an optional string `schema`, return the view
+ definition.
+ """
+
+ raise NotImplementedError()
+
+ def get_indexes(self, connection, table_name, schema=None, **kw):
+ """Return information about indexes in `table_name`.
+
+ Given a :class:`_engine.Connection`, a string
+ `table_name` and an optional string `schema`, return index
+ information as a list of dictionaries with these keys:
+
+ name
+ the index's name
+
+ column_names
+ list of column names in order
+
+ unique
+ boolean
+ """
+
+ raise NotImplementedError()
+
+ def get_unique_constraints(
+ self, connection, table_name, schema=None, **kw
+ ):
+ r"""Return information about unique constraints in `table_name`.
+
+ Given a string `table_name` and an optional string `schema`, return
+ unique constraint information as a list of dicts with these keys:
+
+ name
+ the unique constraint's name
+
+ column_names
+ list of column names in order
+
+ \**kw
+ other options passed to the dialect's get_unique_constraints()
+ method.
+
+ .. versionadded:: 0.9.0
+
+ """
+
+ raise NotImplementedError()
+
+ def get_check_constraints(self, connection, table_name, schema=None, **kw):
+ r"""Return information about check constraints in `table_name`.
+
+ Given a string `table_name` and an optional string `schema`, return
+ check constraint information as a list of dicts with these keys:
+
+ * ``name`` -
+ the check constraint's name
+
+ * ``sqltext`` -
+ the check constraint's SQL expression
+
+ * ``**kw`` -
+ other options passed to the dialect's get_check_constraints()
+ method.
+
+ .. versionadded:: 1.1.0
+
+ """
+
+ raise NotImplementedError()
+
+ def get_table_comment(self, connection, table_name, schema=None, **kw):
+ r"""Return the "comment" for the table identified by `table_name`.
+
+ Given a string `table_name` and an optional string `schema`, return
+ table comment information as a dictionary with this key:
+
+ text
+ text of the comment
+
+ Raises ``NotImplementedError`` for dialects that don't support
+ comments.
+
+ .. versionadded:: 1.2
+
+ """
+
+ raise NotImplementedError()
+
+ def normalize_name(self, name):
+ """convert the given name to lowercase if it is detected as
+ case insensitive.
+
+ This method is only used if the dialect defines
+ requires_name_normalize=True.
+
+ """
+ raise NotImplementedError()
+
+ def denormalize_name(self, name):
+ """convert the given name to a case insensitive identifier
+ for the backend if it is an all-lowercase name.
+
+ This method is only used if the dialect defines
+ requires_name_normalize=True.
+
+ """
+ raise NotImplementedError()
+
+ def has_table(self, connection, table_name, schema=None, **kw):
+ """For internal dialect use, check the existence of a particular table
+ in the database.
+
+ Given a :class:`_engine.Connection` object, a string table_name and
+ optional schema name, return True if the given table exists in the
+ database, False otherwise.
+
+ This method serves as the underlying implementation of the
+ public facing :meth:`.Inspector.has_table` method, and is also used
+ internally to implement the "checkfirst" behavior for methods like
+ :meth:`_schema.Table.create` and :meth:`_schema.MetaData.create_all`.
+
+ .. note:: This method is used internally by SQLAlchemy, and is
+ published so that third-party dialects may provide an
+ implementation. It is **not** the public API for checking for table
+ presence. Please use the :meth:`.Inspector.has_table` method.
+ Alternatively, for legacy cross-compatibility, the
+ :meth:`_engine.Engine.has_table` method may be used.
+
+ """
+
+ raise NotImplementedError()
+
+ def has_index(self, connection, table_name, index_name, schema=None):
+ """Check the existence of a particular index name in the database.
+
+ Given a :class:`_engine.Connection` object, a string
+ `table_name` and string index name, return True if an index of the
+ given name on the given table exists, false otherwise.
+
+ The :class:`.DefaultDialect` implements this in terms of the
+ :meth:`.Dialect.has_table` and :meth:`.Dialect.get_indexes` methods,
+ however dialects can implement a more performant version.
+
+
+ .. versionadded:: 1.4
+
+ """
+
+ raise NotImplementedError()
+
+ def has_sequence(self, connection, sequence_name, schema=None, **kw):
+ """Check the existence of a particular sequence in the database.
+
+ Given a :class:`_engine.Connection` object and a string
+ `sequence_name`, return True if the given sequence exists in
+ the database, False otherwise.
+ """
+
+ raise NotImplementedError()
+
+ def _get_server_version_info(self, connection):
+ """Retrieve the server version info from the given connection.
+
+ This is used by the default implementation to populate the
+ "server_version_info" attribute and is called exactly
+ once upon first connect.
+
+ """
+
+ raise NotImplementedError()
+
+ def _get_default_schema_name(self, connection):
+ """Return the string name of the currently selected schema from
+ the given connection.
+
+ This is used by the default implementation to populate the
+ "default_schema_name" attribute and is called exactly
+ once upon first connect.
+
+ """
+
+ raise NotImplementedError()
+
+ def do_begin(self, dbapi_connection):
+ """Provide an implementation of ``connection.begin()``, given a
+ DB-API connection.
+
+ The DBAPI has no dedicated "begin" method and it is expected
+ that transactions are implicit. This hook is provided for those
+ DBAPIs that might need additional help in this area.
+
+ Note that :meth:`.Dialect.do_begin` is not called unless a
+ :class:`.Transaction` object is in use. The
+ :meth:`.Dialect.do_autocommit`
+ hook is provided for DBAPIs that need some extra commands emitted
+ after a commit in order to enter the next transaction, when the
+ SQLAlchemy :class:`_engine.Connection`
+ is used in its default "autocommit"
+ mode.
+
+ :param dbapi_connection: a DBAPI connection, typically
+ proxied within a :class:`.ConnectionFairy`.
+
+ """
+
+ raise NotImplementedError()
+
+ def do_rollback(self, dbapi_connection):
+ """Provide an implementation of ``connection.rollback()``, given
+ a DB-API connection.
+
+ :param dbapi_connection: a DBAPI connection, typically
+ proxied within a :class:`.ConnectionFairy`.
+
+ """
+
+ raise NotImplementedError()
+
+ def do_commit(self, dbapi_connection):
+ """Provide an implementation of ``connection.commit()``, given a
+ DB-API connection.
+
+ :param dbapi_connection: a DBAPI connection, typically
+ proxied within a :class:`.ConnectionFairy`.
+
+ """
+
+ raise NotImplementedError()
+
+ def do_close(self, dbapi_connection):
+ """Provide an implementation of ``connection.close()``, given a DBAPI
+ connection.
+
+ This hook is called by the :class:`_pool.Pool`
+ when a connection has been
+ detached from the pool, or is being returned beyond the normal
+ capacity of the pool.
+
+ """
+
+ raise NotImplementedError()
+
+ def do_set_input_sizes(self, cursor, list_of_tuples, context):
+ """invoke the cursor.setinputsizes() method with appropriate arguments
+
+ This hook is called if the dialect.use_inputsizes flag is set to True.
+ Parameter data is passed in a list of tuples (paramname, dbtype,
+ sqltype), where ``paramname`` is the key of the parameter in the
+ statement, ``dbtype`` is the DBAPI datatype and ``sqltype`` is the
+ SQLAlchemy type. The order of tuples is in the correct parameter order.
+
+ .. versionadded:: 1.4
+
+
+ """
+ raise NotImplementedError()
+
+ def create_xid(self):
+ """Create a two-phase transaction ID.
+
+ This id will be passed to do_begin_twophase(),
+ do_rollback_twophase(), do_commit_twophase(). Its format is
+ unspecified.
+ """
+
+ raise NotImplementedError()
+
+ def do_savepoint(self, connection, name):
+ """Create a savepoint with the given name.
+
+ :param connection: a :class:`_engine.Connection`.
+ :param name: savepoint name.
+
+ """
+
+ raise NotImplementedError()
+
+ def do_rollback_to_savepoint(self, connection, name):
+ """Rollback a connection to the named savepoint.
+
+ :param connection: a :class:`_engine.Connection`.
+ :param name: savepoint name.
+
+ """
+
+ raise NotImplementedError()
+
+ def do_release_savepoint(self, connection, name):
+ """Release the named savepoint on a connection.
+
+ :param connection: a :class:`_engine.Connection`.
+ :param name: savepoint name.
+ """
+
+ raise NotImplementedError()
+
+ def do_begin_twophase(self, connection, xid):
+ """Begin a two phase transaction on the given connection.
+
+ :param connection: a :class:`_engine.Connection`.
+ :param xid: xid
+
+ """
+
+ raise NotImplementedError()
+
+ def do_prepare_twophase(self, connection, xid):
+ """Prepare a two phase transaction on the given connection.
+
+ :param connection: a :class:`_engine.Connection`.
+ :param xid: xid
+
+ """
+
+ raise NotImplementedError()
+
+ def do_rollback_twophase(
+ self, connection, xid, is_prepared=True, recover=False
+ ):
+ """Rollback a two phase transaction on the given connection.
+
+ :param connection: a :class:`_engine.Connection`.
+ :param xid: xid
+ :param is_prepared: whether or not
+ :meth:`.TwoPhaseTransaction.prepare` was called.
+ :param recover: if the recover flag was passed.
+
+ """
+
+ raise NotImplementedError()
+
+ def do_commit_twophase(
+ self, connection, xid, is_prepared=True, recover=False
+ ):
+ """Commit a two phase transaction on the given connection.
+
+
+ :param connection: a :class:`_engine.Connection`.
+ :param xid: xid
+ :param is_prepared: whether or not
+ :meth:`.TwoPhaseTransaction.prepare` was called.
+ :param recover: if the recover flag was passed.
+
+ """
+
+ raise NotImplementedError()
+
+ def do_recover_twophase(self, connection):
+ """Recover list of uncommitted prepared two phase transaction
+ identifiers on the given connection.
+
+ :param connection: a :class:`_engine.Connection`.
+
+ """
+
+ raise NotImplementedError()
+
+ def do_executemany(self, cursor, statement, parameters, context=None):
+ """Provide an implementation of ``cursor.executemany(statement,
+ parameters)``."""
+
+ raise NotImplementedError()
+
+ def do_execute(self, cursor, statement, parameters, context=None):
+ """Provide an implementation of ``cursor.execute(statement,
+ parameters)``."""
+
+ raise NotImplementedError()
+
+ def do_execute_no_params(
+ self, cursor, statement, parameters, context=None
+ ):
+ """Provide an implementation of ``cursor.execute(statement)``.
+
+ The parameter collection should not be sent.
+
+ """
+
+ raise NotImplementedError()
+
+ def is_disconnect(self, e, connection, cursor):
+ """Return True if the given DB-API error indicates an invalid
+ connection"""
+
+ raise NotImplementedError()
+
+ def connect(self, *cargs, **cparams):
+ r"""Establish a connection using this dialect's DBAPI.
+
+ The default implementation of this method is::
+
+ def connect(self, *cargs, **cparams):
+ return self.dbapi.connect(*cargs, **cparams)
+
+ The ``*cargs, **cparams`` parameters are generated directly
+ from this dialect's :meth:`.Dialect.create_connect_args` method.
+
+ This method may be used for dialects that need to perform programmatic
+ per-connection steps when a new connection is procured from the
+ DBAPI.
+
+
+ :param \*cargs: positional parameters returned from the
+ :meth:`.Dialect.create_connect_args` method
+
+ :param \*\*cparams: keyword parameters returned from the
+ :meth:`.Dialect.create_connect_args` method.
+
+ :return: a DBAPI connection, typically from the :pep:`249` module
+ level ``.connect()`` function.
+
+ .. seealso::
+
+ :meth:`.Dialect.create_connect_args`
+
+ :meth:`.Dialect.on_connect`
+
+ """
+
+ def on_connect_url(self, url):
+ """return a callable which sets up a newly created DBAPI connection.
+
+ This method is a new hook that supersedes the
+ :meth:`_engine.Dialect.on_connect` method when implemented by a
+ dialect. When not implemented by a dialect, it invokes the
+ :meth:`_engine.Dialect.on_connect` method directly to maintain
+ compatibility with existing dialects. There is no deprecation
+ for :meth:`_engine.Dialect.on_connect` expected.
+
+ The callable should accept a single argument "conn" which is the
+ DBAPI connection itself. The inner callable has no
+ return value.
+
+ E.g.::
+
+ class MyDialect(default.DefaultDialect):
+ # ...
+
+ def on_connect_url(self, url):
+ def do_on_connect(connection):
+ connection.execute("SET SPECIAL FLAGS etc")
+
+ return do_on_connect
+
+ This is used to set dialect-wide per-connection options such as
+ isolation modes, Unicode modes, etc.
+
+ This method differs from :meth:`_engine.Dialect.on_connect` in that
+ it is passed the :class:`_engine.URL` object that's relevant to the
+ connect args. Normally the only way to get this is from the
+ :meth:`_engine.Dialect.on_connect` hook is to look on the
+ :class:`_engine.Engine` itself, however this URL object may have been
+ replaced by plugins.
+
+ .. note::
+
+ The default implementation of
+ :meth:`_engine.Dialect.on_connect_url` is to invoke the
+ :meth:`_engine.Dialect.on_connect` method. Therefore if a dialect
+ implements this method, the :meth:`_engine.Dialect.on_connect`
+ method **will not be called** unless the overriding dialect calls
+ it directly from here.
+
+ .. versionadded:: 1.4.3 added :meth:`_engine.Dialect.on_connect_url`
+ which normally calls into :meth:`_engine.Dialect.on_connect`.
+
+ :param url: a :class:`_engine.URL` object representing the
+ :class:`_engine.URL` that was passed to the
+ :meth:`_engine.Dialect.create_connect_args` method.
+
+ :return: a callable that accepts a single DBAPI connection as an
+ argument, or None.
+
+ .. seealso::
+
+ :meth:`_engine.Dialect.on_connect`
+
+ """
+ return self.on_connect()
+
+ def on_connect(self):
+ """return a callable which sets up a newly created DBAPI connection.
+
+ The callable should accept a single argument "conn" which is the
+ DBAPI connection itself. The inner callable has no
+ return value.
+
+ E.g.::
+
+ class MyDialect(default.DefaultDialect):
+ # ...
+
+ def on_connect(self):
+ def do_on_connect(connection):
+ connection.execute("SET SPECIAL FLAGS etc")
+
+ return do_on_connect
+
+ This is used to set dialect-wide per-connection options such as
+ isolation modes, Unicode modes, etc.
+
+ The "do_on_connect" callable is invoked by using the
+ :meth:`_events.PoolEvents.connect` event
+ hook, then unwrapping the DBAPI connection and passing it into the
+ callable.
+
+ .. versionchanged:: 1.4 the on_connect hook is no longer called twice
+ for the first connection of a dialect. The on_connect hook is still
+ called before the :meth:`_engine.Dialect.initialize` method however.
+
+ .. versionchanged:: 1.4.3 the on_connect hook is invoked from a new
+ method on_connect_url that passes the URL that was used to create
+ the connect args. Dialects can implement on_connect_url instead
+ of on_connect if they need the URL object that was used for the
+ connection in order to get additional context.
+
+ If None is returned, no event listener is generated.
+
+ :return: a callable that accepts a single DBAPI connection as an
+ argument, or None.
+
+ .. seealso::
+
+ :meth:`.Dialect.connect` - allows the DBAPI ``connect()`` sequence
+ itself to be controlled.
+
+ :meth:`.Dialect.on_connect_url` - supersedes
+ :meth:`.Dialect.on_connect` to also receive the
+ :class:`_engine.URL` object in context.
+
+ """
+ return None
+
+ def reset_isolation_level(self, dbapi_conn):
+ """Given a DBAPI connection, revert its isolation to the default.
+
+ Note that this is a dialect-level method which is used as part
+ of the implementation of the :class:`_engine.Connection` and
+ :class:`_engine.Engine`
+ isolation level facilities; these APIs should be preferred for
+ most typical use cases.
+
+ .. seealso::
+
+ :meth:`_engine.Connection.get_isolation_level`
+ - view current level
+
+ :attr:`_engine.Connection.default_isolation_level`
+ - view default level
+
+ :paramref:`.Connection.execution_options.isolation_level` -
+ set per :class:`_engine.Connection` isolation level
+
+ :paramref:`_sa.create_engine.isolation_level` -
+ set per :class:`_engine.Engine` isolation level
+
+ """
+
+ raise NotImplementedError()
+
+ def set_isolation_level(self, dbapi_conn, level):
+ """Given a DBAPI connection, set its isolation level.
+
+ Note that this is a dialect-level method which is used as part
+ of the implementation of the :class:`_engine.Connection` and
+ :class:`_engine.Engine`
+ isolation level facilities; these APIs should be preferred for
+ most typical use cases.
+
+ .. seealso::
+
+ :meth:`_engine.Connection.get_isolation_level`
+ - view current level
+
+ :attr:`_engine.Connection.default_isolation_level`
+ - view default level
+
+ :paramref:`.Connection.execution_options.isolation_level` -
+ set per :class:`_engine.Connection` isolation level
+
+ :paramref:`_sa.create_engine.isolation_level` -
+ set per :class:`_engine.Engine` isolation level
+
+ """
+
+ raise NotImplementedError()
+
+ def get_isolation_level(self, dbapi_conn):
+ """Given a DBAPI connection, return its isolation level.
+
+ When working with a :class:`_engine.Connection` object,
+ the corresponding
+ DBAPI connection may be procured using the
+ :attr:`_engine.Connection.connection` accessor.
+
+ Note that this is a dialect-level method which is used as part
+ of the implementation of the :class:`_engine.Connection` and
+ :class:`_engine.Engine` isolation level facilities;
+ these APIs should be preferred for most typical use cases.
+
+
+ .. seealso::
+
+ :meth:`_engine.Connection.get_isolation_level`
+ - view current level
+
+ :attr:`_engine.Connection.default_isolation_level`
+ - view default level
+
+ :paramref:`.Connection.execution_options.isolation_level` -
+ set per :class:`_engine.Connection` isolation level
+
+ :paramref:`_sa.create_engine.isolation_level` -
+ set per :class:`_engine.Engine` isolation level
+
+
+ """
+
+ raise NotImplementedError()
+
+ def get_default_isolation_level(self, dbapi_conn):
+ """Given a DBAPI connection, return its isolation level, or
+ a default isolation level if one cannot be retrieved.
+
+ This method may only raise NotImplementedError and
+ **must not raise any other exception**, as it is used implicitly upon
+ first connect.
+
+ The method **must return a value** for a dialect that supports
+ isolation level settings, as this level is what will be reverted
+ towards when a per-connection isolation level change is made.
+
+ The method defaults to using the :meth:`.Dialect.get_isolation_level`
+ method unless overridden by a dialect.
+
+ .. versionadded:: 1.3.22
+
+ """
+ raise NotImplementedError()
+
+ @classmethod
+ def get_dialect_cls(cls, url):
+ """Given a URL, return the :class:`.Dialect` that will be used.
+
+ This is a hook that allows an external plugin to provide functionality
+ around an existing dialect, by allowing the plugin to be loaded
+ from the url based on an entrypoint, and then the plugin returns
+ the actual dialect to be used.
+
+ By default this just returns the cls.
+
+ .. versionadded:: 1.0.3
+
+ """
+ return cls
+
+ @classmethod
+ def load_provisioning(cls):
+ """set up the provision.py module for this dialect.
+
+ For dialects that include a provision.py module that sets up
+ provisioning followers, this method should initiate that process.
+
+ A typical implementation would be::
+
+ @classmethod
+ def load_provisioning(cls):
+ __import__("mydialect.provision")
+
+ The default method assumes a module named ``provision.py`` inside
+ the owning package of the current dialect, based on the ``__module__``
+ attribute::
+
+ @classmethod
+ def load_provisioning(cls):
+ package = ".".join(cls.__module__.split(".")[0:-1])
+ try:
+ __import__(package + ".provision")
+ except ImportError:
+ pass
+
+ .. versionadded:: 1.3.14
+
+ """
+
+ @classmethod
+ def engine_created(cls, engine):
+ """A convenience hook called before returning the final
+ :class:`_engine.Engine`.
+
+ If the dialect returned a different class from the
+ :meth:`.get_dialect_cls`
+ method, then the hook is called on both classes, first on
+ the dialect class returned by the :meth:`.get_dialect_cls` method and
+ then on the class on which the method was called.
+
+ The hook should be used by dialects and/or wrappers to apply special
+ events to the engine or its components. In particular, it allows
+ a dialect-wrapping class to apply dialect-level events.
+
+ .. versionadded:: 1.0.3
+
+ """
+
+ def get_driver_connection(self, connection):
+ """Returns the connection object as returned by the external driver
+ package.
+
+ For normal dialects that use a DBAPI compliant driver this call
+ will just return the ``connection`` passed as argument.
+ For dialects that instead adapt a non DBAPI compliant driver, like
+ when adapting an asyncio driver, this call will return the
+ connection-like object as returned by the driver.
+
+ .. versionadded:: 1.4.24
+
+ """
+ raise NotImplementedError()
+
+
+class CreateEnginePlugin(object):
+ """A set of hooks intended to augment the construction of an
+ :class:`_engine.Engine` object based on entrypoint names in a URL.
+
+ The purpose of :class:`_engine.CreateEnginePlugin` is to allow third-party
+ systems to apply engine, pool and dialect level event listeners without
+ the need for the target application to be modified; instead, the plugin
+ names can be added to the database URL. Target applications for
+ :class:`_engine.CreateEnginePlugin` include:
+
+ * connection and SQL performance tools, e.g. which use events to track
+ number of checkouts and/or time spent with statements
+
+ * connectivity plugins such as proxies
+
+ A rudimentary :class:`_engine.CreateEnginePlugin` that attaches a logger
+ to an :class:`_engine.Engine` object might look like::
+
+
+ import logging
+
+ from sqlalchemy.engine import CreateEnginePlugin
+ from sqlalchemy import event
+
+ class LogCursorEventsPlugin(CreateEnginePlugin):
+ def __init__(self, url, kwargs):
+ # consume the parameter "log_cursor_logging_name" from the
+ # URL query
+ logging_name = url.query.get("log_cursor_logging_name", "log_cursor")
+
+ self.log = logging.getLogger(logging_name)
+
+ def update_url(self, url):
+ "update the URL to one that no longer includes our parameters"
+ return url.difference_update_query(["log_cursor_logging_name"])
+
+ def engine_created(self, engine):
+ "attach an event listener after the new Engine is constructed"
+ event.listen(engine, "before_cursor_execute", self._log_event)
+
+
+ def _log_event(
+ self,
+ conn,
+ cursor,
+ statement,
+ parameters,
+ context,
+ executemany):
+
+ self.log.info("Plugin logged cursor event: %s", statement)
+
+
+
+ Plugins are registered using entry points in a similar way as that
+ of dialects::
+
+ entry_points={
+ 'sqlalchemy.plugins': [
+ 'log_cursor_plugin = myapp.plugins:LogCursorEventsPlugin'
+ ]
+
+ A plugin that uses the above names would be invoked from a database
+ URL as in::
+
+ from sqlalchemy import create_engine
+
+ engine = create_engine(
+ "mysql+pymysql://scott:tiger@localhost/test?"
+ "plugin=log_cursor_plugin&log_cursor_logging_name=mylogger"
+ )
+
+ The ``plugin`` URL parameter supports multiple instances, so that a URL
+ may specify multiple plugins; they are loaded in the order stated
+ in the URL::
+
+ engine = create_engine(
+ "mysql+pymysql://scott:tiger@localhost/test?"
+ "plugin=plugin_one&plugin=plugin_twp&plugin=plugin_three")
+
+ The plugin names may also be passed directly to :func:`_sa.create_engine`
+ using the :paramref:`_sa.create_engine.plugins` argument::
+
+ engine = create_engine(
+ "mysql+pymysql://scott:tiger@localhost/test",
+ plugins=["myplugin"])
+
+ .. versionadded:: 1.2.3 plugin names can also be specified
+ to :func:`_sa.create_engine` as a list
+
+ A plugin may consume plugin-specific arguments from the
+ :class:`_engine.URL` object as well as the ``kwargs`` dictionary, which is
+ the dictionary of arguments passed to the :func:`_sa.create_engine`
+ call. "Consuming" these arguments includes that they must be removed
+ when the plugin initializes, so that the arguments are not passed along
+ to the :class:`_engine.Dialect` constructor, where they will raise an
+ :class:`_exc.ArgumentError` because they are not known by the dialect.
+
+ As of version 1.4 of SQLAlchemy, arguments should continue to be consumed
+ from the ``kwargs`` dictionary directly, by removing the values with a
+ method such as ``dict.pop``. Arguments from the :class:`_engine.URL` object
+ should be consumed by implementing the
+ :meth:`_engine.CreateEnginePlugin.update_url` method, returning a new copy
+ of the :class:`_engine.URL` with plugin-specific parameters removed::
+
+ class MyPlugin(CreateEnginePlugin):
+ def __init__(self, url, kwargs):
+ self.my_argument_one = url.query['my_argument_one']
+ self.my_argument_two = url.query['my_argument_two']
+ self.my_argument_three = kwargs.pop('my_argument_three', None)
+
+ def update_url(self, url):
+ return url.difference_update_query(
+ ["my_argument_one", "my_argument_two"]
+ )
+
+ Arguments like those illustrated above would be consumed from a
+ :func:`_sa.create_engine` call such as::
+
+ from sqlalchemy import create_engine
+
+ engine = create_engine(
+ "mysql+pymysql://scott:tiger@localhost/test?"
+ "plugin=myplugin&my_argument_one=foo&my_argument_two=bar",
+ my_argument_three='bat'
+ )
+
+ .. versionchanged:: 1.4
+
+ The :class:`_engine.URL` object is now immutable; a
+ :class:`_engine.CreateEnginePlugin` that needs to alter the
+ :class:`_engine.URL` should implement the newly added
+ :meth:`_engine.CreateEnginePlugin.update_url` method, which
+ is invoked after the plugin is constructed.
+
+ For migration, construct the plugin in the following way, checking
+ for the existence of the :meth:`_engine.CreateEnginePlugin.update_url`
+ method to detect which version is running::
+
+ class MyPlugin(CreateEnginePlugin):
+ def __init__(self, url, kwargs):
+ if hasattr(CreateEnginePlugin, "update_url"):
+ # detect the 1.4 API
+ self.my_argument_one = url.query['my_argument_one']
+ self.my_argument_two = url.query['my_argument_two']
+ else:
+ # detect the 1.3 and earlier API - mutate the
+ # URL directly
+ self.my_argument_one = url.query.pop('my_argument_one')
+ self.my_argument_two = url.query.pop('my_argument_two')
+
+ self.my_argument_three = kwargs.pop('my_argument_three', None)
+
+ def update_url(self, url):
+ # this method is only called in the 1.4 version
+ return url.difference_update_query(
+ ["my_argument_one", "my_argument_two"]
+ )
+
+ .. seealso::
+
+ :ref:`change_5526` - overview of the :class:`_engine.URL` change which
+ also includes notes regarding :class:`_engine.CreateEnginePlugin`.
+
+
+ When the engine creation process completes and produces the
+ :class:`_engine.Engine` object, it is again passed to the plugin via the
+ :meth:`_engine.CreateEnginePlugin.engine_created` hook. In this hook, additional
+ changes can be made to the engine, most typically involving setup of
+ events (e.g. those defined in :ref:`core_event_toplevel`).
+
+ .. versionadded:: 1.1
+
+ """ # noqa: E501
+
+ def __init__(self, url, kwargs):
+ """Construct a new :class:`.CreateEnginePlugin`.
+
+ The plugin object is instantiated individually for each call
+ to :func:`_sa.create_engine`. A single :class:`_engine.
+ Engine` will be
+ passed to the :meth:`.CreateEnginePlugin.engine_created` method
+ corresponding to this URL.
+
+ :param url: the :class:`_engine.URL` object. The plugin may inspect
+ the :class:`_engine.URL` for arguments. Arguments used by the
+ plugin should be removed, by returning an updated :class:`_engine.URL`
+ from the :meth:`_engine.CreateEnginePlugin.update_url` method.
+
+ .. versionchanged:: 1.4
+
+ The :class:`_engine.URL` object is now immutable, so a
+ :class:`_engine.CreateEnginePlugin` that needs to alter the
+ :class:`_engine.URL` object should implement the
+ :meth:`_engine.CreateEnginePlugin.update_url` method.
+
+ :param kwargs: The keyword arguments passed to
+ :func:`_sa.create_engine`.
+
+ """
+ self.url = url
+
+ def update_url(self, url):
+ """Update the :class:`_engine.URL`.
+
+ A new :class:`_engine.URL` should be returned. This method is
+ typically used to consume configuration arguments from the
+ :class:`_engine.URL` which must be removed, as they will not be
+ recognized by the dialect. The
+ :meth:`_engine.URL.difference_update_query` method is available
+ to remove these arguments. See the docstring at
+ :class:`_engine.CreateEnginePlugin` for an example.
+
+
+ .. versionadded:: 1.4
+
+ """
+
+ def handle_dialect_kwargs(self, dialect_cls, dialect_args):
+ """parse and modify dialect kwargs"""
+
+ def handle_pool_kwargs(self, pool_cls, pool_args):
+ """parse and modify pool kwargs"""
+
+ def engine_created(self, engine):
+ """Receive the :class:`_engine.Engine`
+ object when it is fully constructed.
+
+ The plugin may make additional changes to the engine, such as
+ registering engine or connection pool events.
+
+ """
+
+
+class ExecutionContext(object):
+ """A messenger object for a Dialect that corresponds to a single
+ execution.
+
+ ExecutionContext should have these data members:
+
+ connection
+ Connection object which can be freely used by default value
+ generators to execute SQL. This Connection should reference the
+ same underlying connection/transactional resources of
+ root_connection.
+
+ root_connection
+ Connection object which is the source of this ExecutionContext. This
+ Connection may have close_with_result=True set, in which case it can
+ only be used once.
+
+ dialect
+ dialect which created this ExecutionContext.
+
+ cursor
+ DB-API cursor procured from the connection,
+
+ compiled
+ if passed to constructor, sqlalchemy.engine.base.Compiled object
+ being executed,
+
+ statement
+ string version of the statement to be executed. Is either
+ passed to the constructor, or must be created from the
+ sql.Compiled object by the time pre_exec() has completed.
+
+ parameters
+ bind parameters passed to the execute() method. For compiled
+ statements, this is a dictionary or list of dictionaries. For
+ textual statements, it should be in a format suitable for the
+ dialect's paramstyle (i.e. dict or list of dicts for non
+ positional, list or list of lists/tuples for positional).
+
+ isinsert
+ True if the statement is an INSERT.
+
+ isupdate
+ True if the statement is an UPDATE.
+
+ should_autocommit
+ True if the statement is a "committable" statement.
+
+ prefetch_cols
+ a list of Column objects for which a client-side default
+ was fired off. Applies to inserts and updates.
+
+ postfetch_cols
+ a list of Column objects for which a server-side default or
+ inline SQL expression value was fired off. Applies to inserts
+ and updates.
+ """
+
+ def create_cursor(self):
+ """Return a new cursor generated from this ExecutionContext's
+ connection.
+
+ Some dialects may wish to change the behavior of
+ connection.cursor(), such as postgresql which may return a PG
+ "server side" cursor.
+ """
+
+ raise NotImplementedError()
+
+ def pre_exec(self):
+ """Called before an execution of a compiled statement.
+
+ If a compiled statement was passed to this ExecutionContext,
+ the `statement` and `parameters` datamembers must be
+ initialized after this statement is complete.
+ """
+
+ raise NotImplementedError()
+
+ def get_out_parameter_values(self, out_param_names):
+ """Return a sequence of OUT parameter values from a cursor.
+
+ For dialects that support OUT parameters, this method will be called
+ when there is a :class:`.SQLCompiler` object which has the
+ :attr:`.SQLCompiler.has_out_parameters` flag set. This flag in turn
+ will be set to True if the statement itself has :class:`.BindParameter`
+ objects that have the ``.isoutparam`` flag set which are consumed by
+ the :meth:`.SQLCompiler.visit_bindparam` method. If the dialect
+ compiler produces :class:`.BindParameter` objects with ``.isoutparam``
+ set which are not handled by :meth:`.SQLCompiler.visit_bindparam`, it
+ should set this flag explicitly.
+
+ The list of names that were rendered for each bound parameter
+ is passed to the method. The method should then return a sequence of
+ values corresponding to the list of parameter objects. Unlike in
+ previous SQLAlchemy versions, the values can be the **raw values** from
+ the DBAPI; the execution context will apply the appropriate type
+ handler based on what's present in self.compiled.binds and update the
+ values. The processed dictionary will then be made available via the
+ ``.out_parameters`` collection on the result object. Note that
+ SQLAlchemy 1.4 has multiple kinds of result object as part of the 2.0
+ transition.
+
+ .. versionadded:: 1.4 - added
+ :meth:`.ExecutionContext.get_out_parameter_values`, which is invoked
+ automatically by the :class:`.DefaultExecutionContext` when there
+ are :class:`.BindParameter` objects with the ``.isoutparam`` flag
+ set. This replaces the practice of setting out parameters within
+ the now-removed ``get_result_proxy()`` method.
+
+ """
+ raise NotImplementedError()
+
+ def post_exec(self):
+ """Called after the execution of a compiled statement.
+
+ If a compiled statement was passed to this ExecutionContext,
+ the `last_insert_ids`, `last_inserted_params`, etc.
+ datamembers should be available after this method completes.
+ """
+
+ raise NotImplementedError()
+
+ def handle_dbapi_exception(self, e):
+ """Receive a DBAPI exception which occurred upon execute, result
+ fetch, etc."""
+
+ raise NotImplementedError()
+
+ def should_autocommit_text(self, statement):
+ """Parse the given textual statement and return True if it refers to
+ a "committable" statement"""
+
+ raise NotImplementedError()
+
+ def lastrow_has_defaults(self):
+ """Return True if the last INSERT or UPDATE row contained
+ inlined or database-side defaults.
+ """
+
+ raise NotImplementedError()
+
+ def get_rowcount(self):
+ """Return the DBAPI ``cursor.rowcount`` value, or in some
+ cases an interpreted value.
+
+ See :attr:`_engine.CursorResult.rowcount` for details on this.
+
+ """
+
+ raise NotImplementedError()
+
+
+@util.deprecated_20_cls(
+ ":class:`.Connectable`",
+ alternative=(
+ "The :class:`_engine.Engine` will be the only Core "
+ "object that features a .connect() method, and the "
+ ":class:`_engine.Connection` will be the only object that features "
+ "an .execute() method."
+ ),
+ constructor=None,
+)
+class Connectable(object):
+ """Interface for an object which supports execution of SQL constructs.
+
+ The two implementations of :class:`.Connectable` are
+ :class:`_engine.Connection` and :class:`_engine.Engine`.
+
+ Connectable must also implement the 'dialect' member which references a
+ :class:`.Dialect` instance.
+
+ """
+
+ def connect(self, **kwargs):
+ """Return a :class:`_engine.Connection` object.
+
+ Depending on context, this may be ``self`` if this object
+ is already an instance of :class:`_engine.Connection`, or a newly
+ procured :class:`_engine.Connection` if this object is an instance
+ of :class:`_engine.Engine`.
+
+ """
+
+ engine = None
+ """The :class:`_engine.Engine` instance referred to by this
+ :class:`.Connectable`.
+
+ May be ``self`` if this is already an :class:`_engine.Engine`.
+
+ """
+
+ def execute(self, object_, *multiparams, **params):
+ """Executes the given construct and returns a
+ :class:`_engine.CursorResult`.
+ """
+ raise NotImplementedError()
+
+ def scalar(self, object_, *multiparams, **params):
+ """Executes and returns the first column of the first row.
+
+ The underlying cursor is closed after execution.
+ """
+ raise NotImplementedError()
+
+ def _run_visitor(self, visitorcallable, element, **kwargs):
+ raise NotImplementedError()
+
+ def _execute_clauseelement(self, elem, multiparams=None, params=None):
+ raise NotImplementedError()
+
+
+class ExceptionContext(object):
+ """Encapsulate information about an error condition in progress.
+
+ This object exists solely to be passed to the
+ :meth:`_events.ConnectionEvents.handle_error` event,
+ supporting an interface that
+ can be extended without backwards-incompatibility.
+
+ .. versionadded:: 0.9.7
+
+ """
+
+ connection = None
+ """The :class:`_engine.Connection` in use during the exception.
+
+ This member is present, except in the case of a failure when
+ first connecting.
+
+ .. seealso::
+
+ :attr:`.ExceptionContext.engine`
+
+
+ """
+
+ engine = None
+ """The :class:`_engine.Engine` in use during the exception.
+
+ This member should always be present, even in the case of a failure
+ when first connecting.
+
+ .. versionadded:: 1.0.0
+
+ """
+
+ cursor = None
+ """The DBAPI cursor object.
+
+ May be None.
+
+ """
+
+ statement = None
+ """String SQL statement that was emitted directly to the DBAPI.
+
+ May be None.
+
+ """
+
+ parameters = None
+ """Parameter collection that was emitted directly to the DBAPI.
+
+ May be None.
+
+ """
+
+ original_exception = None
+ """The exception object which was caught.
+
+ This member is always present.
+
+ """
+
+ sqlalchemy_exception = None
+ """The :class:`sqlalchemy.exc.StatementError` which wraps the original,
+ and will be raised if exception handling is not circumvented by the event.
+
+ May be None, as not all exception types are wrapped by SQLAlchemy.
+ For DBAPI-level exceptions that subclass the dbapi's Error class, this
+ field will always be present.
+
+ """
+
+ chained_exception = None
+ """The exception that was returned by the previous handler in the
+ exception chain, if any.
+
+ If present, this exception will be the one ultimately raised by
+ SQLAlchemy unless a subsequent handler replaces it.
+
+ May be None.
+
+ """
+
+ execution_context = None
+ """The :class:`.ExecutionContext` corresponding to the execution
+ operation in progress.
+
+ This is present for statement execution operations, but not for
+ operations such as transaction begin/end. It also is not present when
+ the exception was raised before the :class:`.ExecutionContext`
+ could be constructed.
+
+ Note that the :attr:`.ExceptionContext.statement` and
+ :attr:`.ExceptionContext.parameters` members may represent a
+ different value than that of the :class:`.ExecutionContext`,
+ potentially in the case where a
+ :meth:`_events.ConnectionEvents.before_cursor_execute` event or similar
+ modified the statement/parameters to be sent.
+
+ May be None.
+
+ """
+
+ is_disconnect = None
+ """Represent whether the exception as occurred represents a "disconnect"
+ condition.
+
+ This flag will always be True or False within the scope of the
+ :meth:`_events.ConnectionEvents.handle_error` handler.
+
+ SQLAlchemy will defer to this flag in order to determine whether or not
+ the connection should be invalidated subsequently. That is, by
+ assigning to this flag, a "disconnect" event which then results in
+ a connection and pool invalidation can be invoked or prevented by
+ changing this flag.
+
+
+ .. note:: The pool "pre_ping" handler enabled using the
+ :paramref:`_sa.create_engine.pool_pre_ping` parameter does **not**
+ consult this event before deciding if the "ping" returned false,
+ as opposed to receiving an unhandled error. For this use case, the
+ :ref:`legacy recipe based on engine_connect() may be used
+ <pool_disconnects_pessimistic_custom>`. A future API allow more
+ comprehensive customization of the "disconnect" detection mechanism
+ across all functions.
+
+ """
+
+ invalidate_pool_on_disconnect = True
+ """Represent whether all connections in the pool should be invalidated
+ when a "disconnect" condition is in effect.
+
+ Setting this flag to False within the scope of the
+ :meth:`_events.ConnectionEvents.handle_error`
+ event will have the effect such
+ that the full collection of connections in the pool will not be
+ invalidated during a disconnect; only the current connection that is the
+ subject of the error will actually be invalidated.
+
+ The purpose of this flag is for custom disconnect-handling schemes where
+ the invalidation of other connections in the pool is to be performed
+ based on other conditions, or even on a per-connection basis.
+
+ .. versionadded:: 1.0.3
+
+ """
+
+
+class AdaptedConnection(object):
+ """Interface of an adapted connection object to support the DBAPI protocol.
+
+ Used by asyncio dialects to provide a sync-style pep-249 facade on top
+ of the asyncio connection/cursor API provided by the driver.
+
+ .. versionadded:: 1.4.24
+
+ """
+
+ __slots__ = ("_connection",)
+
+ @property
+ def driver_connection(self):
+ """The connection object as returned by the driver after a connect."""
+ return self._connection
+
+ def run_async(self, fn):
+ """Run the awaitable returned by the given function, which is passed
+ the raw asyncio driver connection.
+
+ This is used to invoke awaitable-only methods on the driver connection
+ within the context of a "synchronous" method, like a connection
+ pool event handler.
+
+ E.g.::
+
+ engine = create_async_engine(...)
+
+ @event.listens_for(engine.sync_engine, "connect")
+ def register_custom_types(dbapi_connection, ...):
+ dbapi_connection.run_async(
+ lambda connection: connection.set_type_codec(
+ 'MyCustomType', encoder, decoder, ...
+ )
+ )
+
+ .. versionadded:: 1.4.30
+
+ .. seealso::
+
+ :ref:`asyncio_events_run_async`
+
+ """
+ return await_only(fn(self._connection))
+
+ def __repr__(self):
+ return "<AdaptedConnection %s>" % self._connection