Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
events.py376 linesDownload Raw Back to pool
1# pool/events.py
2# Copyright (C) 2005-2026 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
7from __future__ import annotations
8
9import typing
10from typing import Any
11from typing import Optional
12from typing import Type
13from typing import Union
14
15from .base import ConnectionPoolEntry
16from .base import Pool
17from .base import PoolProxiedConnection
18from .base import PoolResetState
19from .. import event
20from .. import util
21
22if typing.TYPE_CHECKING:
23    from ..engine import Engine
24    from ..engine.interfaces import DBAPIConnection
25
26
27class PoolEvents(event.Events[Pool]):
28    """Available events for :class:`_pool.Pool`.
29
30    The methods here define the name of an event as well
31    as the names of members that are passed to listener
32    functions.
33
34    When using an :class:`.Engine` object created via :func:`_sa.create_engine`
35    (or indirectly via :func:`.create_async_engine`), :class:`.PoolEvents`
36    listeners are expected to be registered in terms of the :class:`.Engine`,
37    which will direct the listeners to the :class:`.Pool` contained within::
38
39        from sqlalchemy import create_engine
40        from sqlalchemy import event
41
42        engine = create_engine("postgresql+psycopg2://scott:tiger@localhost/test")
43
44
45        @event.listens_for(engine, "checkout")
46        def my_on_checkout(dbapi_conn, connection_rec, connection_proxy):
47            "handle an on checkout event"
48
49    :class:`.PoolEvents` may also be registered with the :class:`_pool.Pool`
50    class, with the :class:`.Engine` class, as well as with instances of
51    :class:`_pool.Pool`.
52
53    .. tip::
54
55        Registering :class:`.PoolEvents` with the :class:`.Engine`, if present,
56        is recommended since the :meth:`.Engine.dispose` method will carry
57        along event listeners from the old pool to the new pool.
58
59    """  # noqa: E501
60
61    _target_class_doc = "SomeEngineOrPool"
62    _dispatch_target = Pool
63
64    @util.preload_module("sqlalchemy.engine")
65    @classmethod
66    def _accept_with(
67        cls,
68        target: Union[Pool, Type[Pool], Engine, Type[Engine]],
69        identifier: str,
70    ) -> Optional[Union[Pool, Type[Pool]]]:
71        if not typing.TYPE_CHECKING:
72            Engine = util.preloaded.engine.Engine
73
74        if isinstance(target, type):
75            if issubclass(target, Engine):
76                return Pool
77            else:
78                assert issubclass(target, Pool)
79                return target
80        elif isinstance(target, Engine):
81            return target.pool
82        elif isinstance(target, Pool):
83            return target
84        elif hasattr(target, "_no_async_engine_events"):
85            target._no_async_engine_events()
86        else:
87            return None
88
89    @classmethod
90    def _listen(
91        cls,
92        event_key: event._EventKey[Pool],
93        **kw: Any,
94    ) -> None:
95        target = event_key.dispatch_target
96
97        kw.setdefault("asyncio", target._is_asyncio)
98
99        event_key.base_listen(**kw)
100
101    def connect(
102        self,
103        dbapi_connection: DBAPIConnection,
104        connection_record: ConnectionPoolEntry,
105    ) -> None:
106        """Called at the moment a particular DBAPI connection is first
107        created for a given :class:`_pool.Pool`.
108
109        This event allows one to capture the point directly after which
110        the DBAPI module-level ``.connect()`` method has been used in order
111        to produce a new DBAPI connection.
112
113        :param dbapi_connection: a DBAPI connection.
114         The :attr:`.ConnectionPoolEntry.dbapi_connection` attribute.
115
116        :param connection_record: the :class:`.ConnectionPoolEntry` managing
117         the DBAPI connection.
118
119        """
120
121    def first_connect(
122        self,
123        dbapi_connection: DBAPIConnection,
124        connection_record: ConnectionPoolEntry,
125    ) -> None:
126        """Called exactly once for the first time a DBAPI connection is
127        checked out from a particular :class:`_pool.Pool`.
128
129        The rationale for :meth:`_events.PoolEvents.first_connect`
130        is to determine
131        information about a particular series of database connections based
132        on the settings used for all connections.  Since a particular
133        :class:`_pool.Pool`
134        refers to a single "creator" function (which in terms
135        of a :class:`_engine.Engine`
136        refers to the URL and connection options used),
137        it is typically valid to make observations about a single connection
138        that can be safely assumed to be valid about all subsequent
139        connections, such as the database version, the server and client
140        encoding settings, collation settings, and many others.
141
142        :param dbapi_connection: a DBAPI connection.
143         The :attr:`.ConnectionPoolEntry.dbapi_connection` attribute.
144
145        :param connection_record: the :class:`.ConnectionPoolEntry` managing
146         the DBAPI connection.
147
148        """
149
150    def checkout(
151        self,
152        dbapi_connection: DBAPIConnection,
153        connection_record: ConnectionPoolEntry,
154        connection_proxy: PoolProxiedConnection,
155    ) -> None:
156        """Called when a connection is retrieved from the Pool.
157
158        :param dbapi_connection: a DBAPI connection.
159         The :attr:`.ConnectionPoolEntry.dbapi_connection` attribute.
160
161        :param connection_record: the :class:`.ConnectionPoolEntry` managing
162         the DBAPI connection.
163
164        :param connection_proxy: the :class:`.PoolProxiedConnection` object
165          which will proxy the public interface of the DBAPI connection for the
166          lifespan of the checkout.
167
168        If you raise a :class:`~sqlalchemy.exc.DisconnectionError`, the current
169        connection will be disposed and a fresh connection retrieved.
170        Processing of all checkout listeners will abort and restart
171        using the new connection.
172
173        .. seealso:: :meth:`_events.ConnectionEvents.engine_connect`
174           - a similar event
175           which occurs upon creation of a new :class:`_engine.Connection`.
176
177        """
178
179    def checkin(
180        self,
181        dbapi_connection: Optional[DBAPIConnection],
182        connection_record: ConnectionPoolEntry,
183    ) -> None:
184        """Called when a connection returns to the pool.
185
186        Note that the connection may be closed, and may be None if the
187        connection has been invalidated.  ``checkin`` will not be called
188        for detached connections.  (They do not return to the pool.)
189
190        :param dbapi_connection: a DBAPI connection.
191         The :attr:`.ConnectionPoolEntry.dbapi_connection` attribute.
192
193        :param connection_record: the :class:`.ConnectionPoolEntry` managing
194         the DBAPI connection.
195
196        """
197
198    @event._legacy_signature(
199        "2.0",
200        ["dbapi_connection", "connection_record"],
201        lambda dbapi_connection, connection_record, reset_state: (
202            dbapi_connection,
203            connection_record,
204        ),
205    )
206    def reset(
207        self,
208        dbapi_connection: DBAPIConnection,
209        connection_record: ConnectionPoolEntry,
210        reset_state: PoolResetState,
211    ) -> None:
212        """Called before the "reset" action occurs for a pooled connection.
213
214        This event represents
215        when the ``rollback()`` method is called on the DBAPI connection
216        before it is returned to the pool or discarded.
217        A custom "reset" strategy may be implemented using this event hook,
218        which may also be combined with disabling the default "reset"
219        behavior using the :paramref:`_pool.Pool.reset_on_return` parameter.
220
221        The primary difference between the :meth:`_events.PoolEvents.reset` and
222        :meth:`_events.PoolEvents.checkin` events are that
223        :meth:`_events.PoolEvents.reset` is called not just for pooled
224        connections that are being returned to the pool, but also for
225        connections that were detached using the
226        :meth:`_engine.Connection.detach` method as well as asyncio connections
227        that are being discarded due to garbage collection taking place on
228        connections before the connection was checked in.
229
230        Note that the event **is not** invoked for connections that were
231        invalidated using :meth:`_engine.Connection.invalidate`.    These
232        events may be intercepted using the :meth:`.PoolEvents.soft_invalidate`
233        and :meth:`.PoolEvents.invalidate` event hooks, and all "connection
234        close" events may be intercepted using :meth:`.PoolEvents.close`.
235
236        The :meth:`_events.PoolEvents.reset` event is usually followed by the
237        :meth:`_events.PoolEvents.checkin` event, except in those
238        cases where the connection is discarded immediately after reset.
239
240        :param dbapi_connection: a DBAPI connection.
241         The :attr:`.ConnectionPoolEntry.dbapi_connection` attribute.
242
243        :param connection_record: the :class:`.ConnectionPoolEntry` managing
244         the DBAPI connection.
245
246        :param reset_state: :class:`.PoolResetState` instance which provides
247         information about the circumstances under which the connection
248         is being reset.
249
250         .. versionadded:: 2.0
251
252        .. seealso::
253
254            :ref:`pool_reset_on_return`
255
256            :meth:`_events.ConnectionEvents.rollback`
257
258            :meth:`_events.ConnectionEvents.commit`
259
260        """
261
262    def invalidate(
263        self,
264        dbapi_connection: DBAPIConnection,
265        connection_record: ConnectionPoolEntry,
266        exception: Optional[BaseException],
267    ) -> None:
268        """Called when a DBAPI connection is to be "invalidated".
269
270        This event is called any time the
271        :meth:`.ConnectionPoolEntry.invalidate` method is invoked, either from
272        API usage or via "auto-invalidation", without the ``soft`` flag.
273
274        The event occurs before a final attempt to call ``.close()`` on the
275        connection occurs.
276
277        :param dbapi_connection: a DBAPI connection.
278         The :attr:`.ConnectionPoolEntry.dbapi_connection` attribute.
279
280        :param connection_record: the :class:`.ConnectionPoolEntry` managing
281         the DBAPI connection.
282
283        :param exception: the exception object corresponding to the reason
284         for this invalidation, if any.  May be ``None``.
285
286        .. seealso::
287
288            :ref:`pool_connection_invalidation`
289
290        """
291
292    def soft_invalidate(
293        self,
294        dbapi_connection: DBAPIConnection,
295        connection_record: ConnectionPoolEntry,
296        exception: Optional[BaseException],
297    ) -> None:
298        """Called when a DBAPI connection is to be "soft invalidated".
299
300        This event is called any time the
301        :meth:`.ConnectionPoolEntry.invalidate`
302        method is invoked with the ``soft`` flag.
303
304        Soft invalidation refers to when the connection record that tracks
305        this connection will force a reconnect after the current connection
306        is checked in.   It does not actively close the dbapi_connection
307        at the point at which it is called.
308
309        :param dbapi_connection: a DBAPI connection.
310         The :attr:`.ConnectionPoolEntry.dbapi_connection` attribute.
311
312        :param connection_record: the :class:`.ConnectionPoolEntry` managing
313         the DBAPI connection.
314
315        :param exception: the exception object corresponding to the reason
316         for this invalidation, if any.  May be ``None``.
317
318        """
319
320    def close(
321        self,
322        dbapi_connection: DBAPIConnection,
323        connection_record: ConnectionPoolEntry,
324    ) -> None:
325        """Called when a DBAPI connection is closed.
326
327        The event is emitted before the close occurs.
328
329        The close of a connection can fail; typically this is because
330        the connection is already closed.  If the close operation fails,
331        the connection is discarded.
332
333        The :meth:`.close` event corresponds to a connection that's still
334        associated with the pool. To intercept close events for detached
335        connections use :meth:`.close_detached`.
336
337        :param dbapi_connection: a DBAPI connection.
338         The :attr:`.ConnectionPoolEntry.dbapi_connection` attribute.
339
340        :param connection_record: the :class:`.ConnectionPoolEntry` managing
341         the DBAPI connection.
342
343        """
344
345    def detach(
346        self,
347        dbapi_connection: DBAPIConnection,
348        connection_record: ConnectionPoolEntry,
349    ) -> None:
350        """Called when a DBAPI connection is "detached" from a pool.
351
352        This event is emitted after the detach occurs.  The connection
353        is no longer associated with the given connection record.
354
355        :param dbapi_connection: a DBAPI connection.
356         The :attr:`.ConnectionPoolEntry.dbapi_connection` attribute.
357
358        :param connection_record: the :class:`.ConnectionPoolEntry` managing
359         the DBAPI connection.
360
361        """
362
363    def close_detached(self, dbapi_connection: DBAPIConnection) -> None:
364        """Called when a detached DBAPI connection is closed.
365
366        The event is emitted before the close occurs.
367
368        The close of a connection can fail; typically this is because
369        the connection is already closed.  If the close operation fails,
370        the connection is discarded.
371
372        :param dbapi_connection: a DBAPI connection.
373         The :attr:`.ConnectionPoolEntry.dbapi_connection` attribute.
374
375        """
376 
codekingpro/portable-devtools · Team Ai