summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/pool
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2020-01-21 18:41:48 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2020-01-21 20:09:39 -0500
commitc506e01324cac524ee15257d31d9821aa8a23b95 (patch)
treee3fef4f33a05b4f8cacd21a7a3e42089694f9a85 /lib/sqlalchemy/pool
parentd8ac1e9e6bfc931d2f14f9846d6924106f56b7e6 (diff)
downloadsqlalchemy-c506e01324cac524ee15257d31d9821aa8a23b95.tar.gz
Reorganize core event modules to avoid import cycles
sqlalchemy.sql.naming was causing a full import of engine due to the DDLEvents dependency. Break out pool, DDL and engine events into new modules specific to those packages; resolve some other import cycles in Core also. Change-Id: Ife8d217e58a26ab3605dd80ee70837968f957eaf
Diffstat (limited to 'lib/sqlalchemy/pool')
-rw-r--r--lib/sqlalchemy/pool/__init__.py1
-rw-r--r--lib/sqlalchemy/pool/events.py236
2 files changed, 237 insertions, 0 deletions
diff --git a/lib/sqlalchemy/pool/__init__.py b/lib/sqlalchemy/pool/__init__.py
index ba9871378..058d595c8 100644
--- a/lib/sqlalchemy/pool/__init__.py
+++ b/lib/sqlalchemy/pool/__init__.py
@@ -17,6 +17,7 @@ regular DB-API connect() methods to be transparently managed by a
SQLAlchemy connection pool.
"""
+from . import events # noqa
from .base import _ConnectionFairy # noqa
from .base import _ConnectionRecord # noqa
from .base import _finalize_fairy # noqa
diff --git a/lib/sqlalchemy/pool/events.py b/lib/sqlalchemy/pool/events.py
new file mode 100644
index 000000000..7a3a0910a
--- /dev/null
+++ b/lib/sqlalchemy/pool/events.py
@@ -0,0 +1,236 @@
+# sqlalchemy/pool/events.py
+# Copyright (C) 2005-2020 the SQLAlchemy authors and contributors
+# <see AUTHORS file>
+#
+# This module is part of SQLAlchemy and is released under
+# the MIT License: http://www.opensource.org/licenses/mit-license.php
+
+from .base import Pool
+from .. import event
+from ..engine.base import Engine
+
+
+class PoolEvents(event.Events):
+ """Available events for :class:`.Pool`.
+
+ The methods here define the name of an event as well
+ as the names of members that are passed to listener
+ functions.
+
+ e.g.::
+
+ from sqlalchemy import event
+
+ def my_on_checkout(dbapi_conn, connection_rec, connection_proxy):
+ "handle an on checkout event"
+
+ event.listen(Pool, 'checkout', my_on_checkout)
+
+ In addition to accepting the :class:`.Pool` class and
+ :class:`.Pool` instances, :class:`.PoolEvents` also accepts
+ :class:`.Engine` objects and the :class:`.Engine` class as
+ targets, which will be resolved to the ``.pool`` attribute of the
+ given engine or the :class:`.Pool` class::
+
+ engine = create_engine("postgresql://scott:tiger@localhost/test")
+
+ # will associate with engine.pool
+ event.listen(engine, 'checkout', my_on_checkout)
+
+ """
+
+ _target_class_doc = "SomeEngineOrPool"
+ _dispatch_target = Pool
+
+ @classmethod
+ def _accept_with(cls, target):
+ if isinstance(target, type):
+ if issubclass(target, Engine):
+ return Pool
+ elif issubclass(target, Pool):
+ return target
+ elif isinstance(target, Engine):
+ return target.pool
+ else:
+ return target
+
+ def connect(self, dbapi_connection, connection_record):
+ """Called at the moment a particular DBAPI connection is first
+ created for a given :class:`.Pool`.
+
+ This event allows one to capture the point directly after which
+ the DBAPI module-level ``.connect()`` method has been used in order
+ to produce a new DBAPI connection.
+
+ :param dbapi_connection: a DBAPI connection.
+
+ :param connection_record: the :class:`._ConnectionRecord` managing the
+ DBAPI connection.
+
+ """
+
+ def first_connect(self, dbapi_connection, connection_record):
+ """Called exactly once for the first time a DBAPI connection is
+ checked out from a particular :class:`.Pool`.
+
+ The rationale for :meth:`.PoolEvents.first_connect` is to determine
+ information about a particular series of database connections based
+ on the settings used for all connections. Since a particular
+ :class:`.Pool` refers to a single "creator" function (which in terms
+ of a :class:`.Engine` refers to the URL and connection options used),
+ it is typically valid to make observations about a single connection
+ that can be safely assumed to be valid about all subsequent
+ connections, such as the database version, the server and client
+ encoding settings, collation settings, and many others.
+
+ :param dbapi_connection: a DBAPI connection.
+
+ :param connection_record: the :class:`._ConnectionRecord` managing the
+ DBAPI connection.
+
+ """
+
+ def checkout(self, dbapi_connection, connection_record, connection_proxy):
+ """Called when a connection is retrieved from the Pool.
+
+ :param dbapi_connection: a DBAPI connection.
+
+ :param connection_record: the :class:`._ConnectionRecord` managing the
+ DBAPI connection.
+
+ :param connection_proxy: the :class:`._ConnectionFairy` object which
+ will proxy the public interface of the DBAPI connection for the
+ lifespan of the checkout.
+
+ If you raise a :class:`~sqlalchemy.exc.DisconnectionError`, the current
+ connection will be disposed and a fresh connection retrieved.
+ Processing of all checkout listeners will abort and restart
+ using the new connection.
+
+ .. seealso:: :meth:`.ConnectionEvents.engine_connect` - a similar event
+ which occurs upon creation of a new :class:`.Connection`.
+
+ """
+
+ def checkin(self, dbapi_connection, connection_record):
+ """Called when a connection returns to the pool.
+
+ Note that the connection may be closed, and may be None if the
+ connection has been invalidated. ``checkin`` will not be called
+ for detached connections. (They do not return to the pool.)
+
+ :param dbapi_connection: a DBAPI connection.
+
+ :param connection_record: the :class:`._ConnectionRecord` managing the
+ DBAPI connection.
+
+ """
+
+ def reset(self, dbapi_connection, connection_record):
+ """Called before the "reset" action occurs for a pooled connection.
+
+ This event represents
+ when the ``rollback()`` method is called on the DBAPI connection
+ before it is returned to the pool. The behavior of "reset" can
+ be controlled, including disabled, using the ``reset_on_return``
+ pool argument.
+
+
+ The :meth:`.PoolEvents.reset` event is usually followed by the
+ :meth:`.PoolEvents.checkin` event is called, except in those
+ cases where the connection is discarded immediately after reset.
+
+ :param dbapi_connection: a DBAPI connection.
+
+ :param connection_record: the :class:`._ConnectionRecord` managing the
+ DBAPI connection.
+
+ .. seealso::
+
+ :meth:`.ConnectionEvents.rollback`
+
+ :meth:`.ConnectionEvents.commit`
+
+ """
+
+ def invalidate(self, dbapi_connection, connection_record, exception):
+ """Called when a DBAPI connection is to be "invalidated".
+
+ This event is called any time the :meth:`._ConnectionRecord.invalidate`
+ method is invoked, either from API usage or via "auto-invalidation",
+ without the ``soft`` flag.
+
+ The event occurs before a final attempt to call ``.close()`` on the
+ connection occurs.
+
+ :param dbapi_connection: a DBAPI connection.
+
+ :param connection_record: the :class:`._ConnectionRecord` managing the
+ DBAPI connection.
+
+ :param exception: the exception object corresponding to the reason
+ for this invalidation, if any. May be ``None``.
+
+ .. versionadded:: 0.9.2 Added support for connection invalidation
+ listening.
+
+ .. seealso::
+
+ :ref:`pool_connection_invalidation`
+
+ """
+
+ def soft_invalidate(self, dbapi_connection, connection_record, exception):
+ """Called when a DBAPI connection is to be "soft invalidated".
+
+ This event is called any time the :meth:`._ConnectionRecord.invalidate`
+ method is invoked with the ``soft`` flag.
+
+ Soft invalidation refers to when the connection record that tracks
+ this connection will force a reconnect after the current connection
+ is checked in. It does not actively close the dbapi_connection
+ at the point at which it is called.
+
+ .. versionadded:: 1.0.3
+
+ """
+
+ def close(self, dbapi_connection, connection_record):
+ """Called when a DBAPI connection is closed.
+
+ The event is emitted before the close occurs.
+
+ The close of a connection can fail; typically this is because
+ the connection is already closed. If the close operation fails,
+ the connection is discarded.
+
+ The :meth:`.close` event corresponds to a connection that's still
+ associated with the pool. To intercept close events for detached
+ connections use :meth:`.close_detached`.
+
+ .. versionadded:: 1.1
+
+ """
+
+ def detach(self, dbapi_connection, connection_record):
+ """Called when a DBAPI connection is "detached" from a pool.
+
+ This event is emitted after the detach occurs. The connection
+ is no longer associated with the given connection record.
+
+ .. versionadded:: 1.1
+
+ """
+
+ def close_detached(self, dbapi_connection):
+ """Called when a detached DBAPI connection is closed.
+
+ The event is emitted before the close occurs.
+
+ The close of a connection can fail; typically this is because
+ the connection is already closed. If the close operation fails,
+ the connection is discarded.
+
+ .. versionadded:: 1.1
+
+ """