Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/sqlalchemy/pool/events.py: 80%

35 statements  

« prev     ^ index     » next       coverage.py v7.0.1, created at 2022-12-25 06:11 +0000

1# sqlalchemy/pool/events.py 

2# Copyright (C) 2005-2022 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 

8from .base import Pool 

9from .. import event 

10from ..engine.base import Engine 

11 

12 

13class PoolEvents(event.Events): 

14 """Available events for :class:`_pool.Pool`. 

15 

16 The methods here define the name of an event as well 

17 as the names of members that are passed to listener 

18 functions. 

19 

20 e.g.:: 

21 

22 from sqlalchemy import event 

23 

24 def my_on_checkout(dbapi_conn, connection_rec, connection_proxy): 

25 "handle an on checkout event" 

26 

27 event.listen(Pool, 'checkout', my_on_checkout) 

28 

29 In addition to accepting the :class:`_pool.Pool` class and 

30 :class:`_pool.Pool` instances, :class:`_events.PoolEvents` also accepts 

31 :class:`_engine.Engine` objects and the :class:`_engine.Engine` class as 

32 targets, which will be resolved to the ``.pool`` attribute of the 

33 given engine or the :class:`_pool.Pool` class:: 

34 

35 engine = create_engine("postgresql://scott:tiger@localhost/test") 

36 

37 # will associate with engine.pool 

38 event.listen(engine, 'checkout', my_on_checkout) 

39 

40 """ 

41 

42 _target_class_doc = "SomeEngineOrPool" 

43 _dispatch_target = Pool 

44 

45 @classmethod 

46 def _accept_with(cls, target): 

47 if isinstance(target, type): 

48 if issubclass(target, Engine): 

49 return Pool 

50 elif issubclass(target, Pool): 

51 return target 

52 elif isinstance(target, Engine): 

53 return target.pool 

54 elif isinstance(target, Pool): 

55 return target 

56 elif hasattr(target, "dispatch") and hasattr( 

57 target.dispatch._events, "_no_async_engine_events" 

58 ): 

59 target.dispatch._events._no_async_engine_events() 

60 else: 

61 return None 

62 

63 @classmethod 

64 def _listen(cls, event_key, **kw): 

65 target = event_key.dispatch_target 

66 

67 kw.setdefault("asyncio", target._is_asyncio) 

68 

69 event_key.base_listen(**kw) 

70 

71 def connect(self, dbapi_connection, connection_record): 

72 """Called at the moment a particular DBAPI connection is first 

73 created for a given :class:`_pool.Pool`. 

74 

75 This event allows one to capture the point directly after which 

76 the DBAPI module-level ``.connect()`` method has been used in order 

77 to produce a new DBAPI connection. 

78 

79 :param dbapi_connection: a DBAPI connection. 

80 The :attr:`._ConnectionRecord.dbapi_connection` attribute. 

81 

82 :param connection_record: the :class:`._ConnectionRecord` managing the 

83 DBAPI connection. 

84 

85 """ 

86 

87 def first_connect(self, dbapi_connection, connection_record): 

88 """Called exactly once for the first time a DBAPI connection is 

89 checked out from a particular :class:`_pool.Pool`. 

90 

91 The rationale for :meth:`_events.PoolEvents.first_connect` 

92 is to determine 

93 information about a particular series of database connections based 

94 on the settings used for all connections. Since a particular 

95 :class:`_pool.Pool` 

96 refers to a single "creator" function (which in terms 

97 of a :class:`_engine.Engine` 

98 refers to the URL and connection options used), 

99 it is typically valid to make observations about a single connection 

100 that can be safely assumed to be valid about all subsequent 

101 connections, such as the database version, the server and client 

102 encoding settings, collation settings, and many others. 

103 

104 :param dbapi_connection: a DBAPI connection. 

105 The :attr:`._ConnectionRecord.dbapi_connection` attribute. 

106 

107 :param connection_record: the :class:`._ConnectionRecord` managing the 

108 DBAPI connection. 

109 

110 """ 

111 

112 def checkout(self, dbapi_connection, connection_record, connection_proxy): 

113 """Called when a connection is retrieved from the Pool. 

114 

115 :param dbapi_connection: a DBAPI connection. 

116 The :attr:`._ConnectionRecord.dbapi_connection` attribute. 

117 

118 :param connection_record: the :class:`._ConnectionRecord` managing the 

119 DBAPI connection. 

120 

121 :param connection_proxy: the :class:`._ConnectionFairy` object which 

122 will proxy the public interface of the DBAPI connection for the 

123 lifespan of the checkout. 

124 

125 If you raise a :class:`~sqlalchemy.exc.DisconnectionError`, the current 

126 connection will be disposed and a fresh connection retrieved. 

127 Processing of all checkout listeners will abort and restart 

128 using the new connection. 

129 

130 .. seealso:: :meth:`_events.ConnectionEvents.engine_connect` 

131 - a similar event 

132 which occurs upon creation of a new :class:`_engine.Connection`. 

133 

134 """ 

135 

136 def checkin(self, dbapi_connection, connection_record): 

137 """Called when a connection returns to the pool. 

138 

139 Note that the connection may be closed, and may be None if the 

140 connection has been invalidated. ``checkin`` will not be called 

141 for detached connections. (They do not return to the pool.) 

142 

143 :param dbapi_connection: a DBAPI connection. 

144 The :attr:`._ConnectionRecord.dbapi_connection` attribute. 

145 

146 :param connection_record: the :class:`._ConnectionRecord` managing the 

147 DBAPI connection. 

148 

149 """ 

150 

151 def reset(self, dbapi_connection, connection_record): 

152 """Called before the "reset" action occurs for a pooled connection. 

153 

154 This event represents when the ``rollback()`` method is called on the 

155 DBAPI connection before it is returned to the pool or discarded. A 

156 custom "reset" strategy may be implemented using this event hook, which 

157 may also be combined with disabling the default "reset" behavior using 

158 the :paramref:`_pool.Pool.reset_on_return` parameter. 

159 

160 The primary difference between the :meth:`_events.PoolEvents.reset` and 

161 :meth:`_events.PoolEvents.checkin` events are that 

162 :meth:`_events.PoolEvents.reset` is called not just for pooled 

163 connections that are being returned to the pool, but also for 

164 connections that were detached using the 

165 :meth:`_engine.Connection.detach` method. 

166 

167 Note that the event **is not** invoked for connections that were 

168 invalidated using :meth:`_engine.Connection.invalidate`. These 

169 events may be intercepted using the :meth:`.PoolEvents.soft_invalidate` 

170 and :meth:`.PoolEvents.invalidate` event hooks, and all "connection 

171 close" events may be intercepted using :meth:`.PoolEvents.close`. 

172 The :meth:`_events.PoolEvents.reset` event is usually followed by the 

173 :meth:`_events.PoolEvents.checkin` event, except in those 

174 cases where the connection is discarded immediately after reset. 

175 

176 In the 1.4 series, the event is also not invoked for asyncio 

177 connections that are being garbage collected without their being 

178 explicitly returned to the pool. This is due to the lack of an event 

179 loop which prevents "reset" operations from taking place. Version 2.0 

180 will feature an enhanced version of :meth:`.PoolEvents.reset` which is 

181 invoked in this scenario while passing additional contextual 

182 information indicating that an event loop is not guaranteed 

183 to be present. 

184 

185 :param dbapi_connection: a DBAPI connection. 

186 The :attr:`._ConnectionRecord.dbapi_connection` attribute. 

187 

188 :param connection_record: the :class:`._ConnectionRecord` managing the 

189 DBAPI connection. 

190 

191 .. seealso:: 

192 

193 :meth:`_events.ConnectionEvents.rollback` 

194 

195 :meth:`_events.ConnectionEvents.commit` 

196 

197 """ 

198 

199 def invalidate(self, dbapi_connection, connection_record, exception): 

200 """Called when a DBAPI connection is to be "invalidated". 

201 

202 This event is called any time the :meth:`._ConnectionRecord.invalidate` 

203 method is invoked, either from API usage or via "auto-invalidation", 

204 without the ``soft`` flag. 

205 

206 The event occurs before a final attempt to call ``.close()`` on the 

207 connection occurs. 

208 

209 :param dbapi_connection: a DBAPI connection. 

210 The :attr:`._ConnectionRecord.dbapi_connection` attribute. 

211 

212 :param connection_record: the :class:`._ConnectionRecord` managing the 

213 DBAPI connection. 

214 

215 :param exception: the exception object corresponding to the reason 

216 for this invalidation, if any. May be ``None``. 

217 

218 .. versionadded:: 0.9.2 Added support for connection invalidation 

219 listening. 

220 

221 .. seealso:: 

222 

223 :ref:`pool_connection_invalidation` 

224 

225 """ 

226 

227 def soft_invalidate(self, dbapi_connection, connection_record, exception): 

228 """Called when a DBAPI connection is to be "soft invalidated". 

229 

230 This event is called any time the :meth:`._ConnectionRecord.invalidate` 

231 method is invoked with the ``soft`` flag. 

232 

233 Soft invalidation refers to when the connection record that tracks 

234 this connection will force a reconnect after the current connection 

235 is checked in. It does not actively close the dbapi_connection 

236 at the point at which it is called. 

237 

238 .. versionadded:: 1.0.3 

239 

240 :param dbapi_connection: a DBAPI connection. 

241 The :attr:`._ConnectionRecord.dbapi_connection` attribute. 

242 

243 :param connection_record: the :class:`._ConnectionRecord` managing the 

244 DBAPI connection. 

245 

246 :param exception: the exception object corresponding to the reason 

247 for this invalidation, if any. May be ``None``. 

248 

249 """ 

250 

251 def close(self, dbapi_connection, connection_record): 

252 """Called when a DBAPI connection is closed. 

253 

254 The event is emitted before the close occurs. 

255 

256 The close of a connection can fail; typically this is because 

257 the connection is already closed. If the close operation fails, 

258 the connection is discarded. 

259 

260 The :meth:`.close` event corresponds to a connection that's still 

261 associated with the pool. To intercept close events for detached 

262 connections use :meth:`.close_detached`. 

263 

264 .. versionadded:: 1.1 

265 

266 :param dbapi_connection: a DBAPI connection. 

267 The :attr:`._ConnectionRecord.dbapi_connection` attribute. 

268 

269 :param connection_record: the :class:`._ConnectionRecord` managing the 

270 DBAPI connection. 

271 

272 """ 

273 

274 def detach(self, dbapi_connection, connection_record): 

275 """Called when a DBAPI connection is "detached" from a pool. 

276 

277 This event is emitted after the detach occurs. The connection 

278 is no longer associated with the given connection record. 

279 

280 .. versionadded:: 1.1 

281 

282 :param dbapi_connection: a DBAPI connection. 

283 The :attr:`._ConnectionRecord.dbapi_connection` attribute. 

284 

285 :param connection_record: the :class:`._ConnectionRecord` managing the 

286 DBAPI connection. 

287 

288 """ 

289 

290 def close_detached(self, dbapi_connection): 

291 """Called when a detached DBAPI connection is closed. 

292 

293 The event is emitted before the close occurs. 

294 

295 The close of a connection can fail; typically this is because 

296 the connection is already closed. If the close operation fails, 

297 the connection is discarded. 

298 

299 .. versionadded:: 1.1 

300 

301 :param dbapi_connection: a DBAPI connection. 

302 The :attr:`._ConnectionRecord.dbapi_connection` attribute. 

303 

304 """