You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

249 lines
8.5KB

  1. # sqlalchemy/pool/events.py
  2. # Copyright (C) 2005-2021 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: http://www.opensource.org/licenses/mit-license.php
  7. from .base import Pool
  8. from .. import event
  9. from ..engine.base import Engine
  10. class PoolEvents(event.Events):
  11. """Available events for :class:`_pool.Pool`.
  12. The methods here define the name of an event as well
  13. as the names of members that are passed to listener
  14. functions.
  15. e.g.::
  16. from sqlalchemy import event
  17. def my_on_checkout(dbapi_conn, connection_rec, connection_proxy):
  18. "handle an on checkout event"
  19. event.listen(Pool, 'checkout', my_on_checkout)
  20. In addition to accepting the :class:`_pool.Pool` class and
  21. :class:`_pool.Pool` instances, :class:`_events.PoolEvents` also accepts
  22. :class:`_engine.Engine` objects and the :class:`_engine.Engine` class as
  23. targets, which will be resolved to the ``.pool`` attribute of the
  24. given engine or the :class:`_pool.Pool` class::
  25. engine = create_engine("postgresql://scott:tiger@localhost/test")
  26. # will associate with engine.pool
  27. event.listen(engine, 'checkout', my_on_checkout)
  28. """
  29. _target_class_doc = "SomeEngineOrPool"
  30. _dispatch_target = Pool
  31. @classmethod
  32. def _accept_with(cls, target):
  33. if isinstance(target, type):
  34. if issubclass(target, Engine):
  35. return Pool
  36. elif issubclass(target, Pool):
  37. return target
  38. elif isinstance(target, Engine):
  39. return target.pool
  40. else:
  41. return target
  42. @classmethod
  43. def _listen(cls, event_key, **kw):
  44. target = event_key.dispatch_target
  45. kw.setdefault("asyncio", target._is_asyncio)
  46. event_key.base_listen(**kw)
  47. def connect(self, dbapi_connection, connection_record):
  48. """Called at the moment a particular DBAPI connection is first
  49. created for a given :class:`_pool.Pool`.
  50. This event allows one to capture the point directly after which
  51. the DBAPI module-level ``.connect()`` method has been used in order
  52. to produce a new DBAPI connection.
  53. :param dbapi_connection: a DBAPI connection.
  54. :param connection_record: the :class:`._ConnectionRecord` managing the
  55. DBAPI connection.
  56. """
  57. def first_connect(self, dbapi_connection, connection_record):
  58. """Called exactly once for the first time a DBAPI connection is
  59. checked out from a particular :class:`_pool.Pool`.
  60. The rationale for :meth:`_events.PoolEvents.first_connect`
  61. is to determine
  62. information about a particular series of database connections based
  63. on the settings used for all connections. Since a particular
  64. :class:`_pool.Pool`
  65. refers to a single "creator" function (which in terms
  66. of a :class:`_engine.Engine`
  67. refers to the URL and connection options used),
  68. it is typically valid to make observations about a single connection
  69. that can be safely assumed to be valid about all subsequent
  70. connections, such as the database version, the server and client
  71. encoding settings, collation settings, and many others.
  72. :param dbapi_connection: a DBAPI connection.
  73. :param connection_record: the :class:`._ConnectionRecord` managing the
  74. DBAPI connection.
  75. """
  76. def checkout(self, dbapi_connection, connection_record, connection_proxy):
  77. """Called when a connection is retrieved from the Pool.
  78. :param dbapi_connection: a DBAPI connection.
  79. :param connection_record: the :class:`._ConnectionRecord` managing the
  80. DBAPI connection.
  81. :param connection_proxy: the :class:`._ConnectionFairy` object which
  82. will proxy the public interface of the DBAPI connection for the
  83. lifespan of the checkout.
  84. If you raise a :class:`~sqlalchemy.exc.DisconnectionError`, the current
  85. connection will be disposed and a fresh connection retrieved.
  86. Processing of all checkout listeners will abort and restart
  87. using the new connection.
  88. .. seealso:: :meth:`_events.ConnectionEvents.engine_connect`
  89. - a similar event
  90. which occurs upon creation of a new :class:`_engine.Connection`.
  91. """
  92. def checkin(self, dbapi_connection, connection_record):
  93. """Called when a connection returns to the pool.
  94. Note that the connection may be closed, and may be None if the
  95. connection has been invalidated. ``checkin`` will not be called
  96. for detached connections. (They do not return to the pool.)
  97. :param dbapi_connection: a DBAPI connection.
  98. :param connection_record: the :class:`._ConnectionRecord` managing the
  99. DBAPI connection.
  100. """
  101. def reset(self, dbapi_connection, connection_record):
  102. """Called before the "reset" action occurs for a pooled connection.
  103. This event represents
  104. when the ``rollback()`` method is called on the DBAPI connection
  105. before it is returned to the pool. The behavior of "reset" can
  106. be controlled, including disabled, using the ``reset_on_return``
  107. pool argument.
  108. The :meth:`_events.PoolEvents.reset` event is usually followed by the
  109. :meth:`_events.PoolEvents.checkin` event is called, except in those
  110. cases where the connection is discarded immediately after reset.
  111. :param dbapi_connection: a DBAPI connection.
  112. :param connection_record: the :class:`._ConnectionRecord` managing the
  113. DBAPI connection.
  114. .. seealso::
  115. :meth:`_events.ConnectionEvents.rollback`
  116. :meth:`_events.ConnectionEvents.commit`
  117. """
  118. def invalidate(self, dbapi_connection, connection_record, exception):
  119. """Called when a DBAPI connection is to be "invalidated".
  120. This event is called any time the :meth:`._ConnectionRecord.invalidate`
  121. method is invoked, either from API usage or via "auto-invalidation",
  122. without the ``soft`` flag.
  123. The event occurs before a final attempt to call ``.close()`` on the
  124. connection occurs.
  125. :param dbapi_connection: a DBAPI connection.
  126. :param connection_record: the :class:`._ConnectionRecord` managing the
  127. DBAPI connection.
  128. :param exception: the exception object corresponding to the reason
  129. for this invalidation, if any. May be ``None``.
  130. .. versionadded:: 0.9.2 Added support for connection invalidation
  131. listening.
  132. .. seealso::
  133. :ref:`pool_connection_invalidation`
  134. """
  135. def soft_invalidate(self, dbapi_connection, connection_record, exception):
  136. """Called when a DBAPI connection is to be "soft invalidated".
  137. This event is called any time the :meth:`._ConnectionRecord.invalidate`
  138. method is invoked with the ``soft`` flag.
  139. Soft invalidation refers to when the connection record that tracks
  140. this connection will force a reconnect after the current connection
  141. is checked in. It does not actively close the dbapi_connection
  142. at the point at which it is called.
  143. .. versionadded:: 1.0.3
  144. """
  145. def close(self, dbapi_connection, connection_record):
  146. """Called when a DBAPI connection is closed.
  147. The event is emitted before the close occurs.
  148. The close of a connection can fail; typically this is because
  149. the connection is already closed. If the close operation fails,
  150. the connection is discarded.
  151. The :meth:`.close` event corresponds to a connection that's still
  152. associated with the pool. To intercept close events for detached
  153. connections use :meth:`.close_detached`.
  154. .. versionadded:: 1.1
  155. """
  156. def detach(self, dbapi_connection, connection_record):
  157. """Called when a DBAPI connection is "detached" from a pool.
  158. This event is emitted after the detach occurs. The connection
  159. is no longer associated with the given connection record.
  160. .. versionadded:: 1.1
  161. """
  162. def close_detached(self, dbapi_connection):
  163. """Called when a detached DBAPI connection is closed.
  164. The event is emitted before the close occurs.
  165. The close of a connection can fail; typically this is because
  166. the connection is already closed. If the close operation fails,
  167. the connection is discarded.
  168. .. versionadded:: 1.1
  169. """