SQLAlchemy 2.0.36__cp313-cp313-win32.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (273) hide show
  1. SQLAlchemy-2.0.36.dist-info/LICENSE +19 -0
  2. SQLAlchemy-2.0.36.dist-info/METADATA +243 -0
  3. SQLAlchemy-2.0.36.dist-info/RECORD +273 -0
  4. SQLAlchemy-2.0.36.dist-info/WHEEL +5 -0
  5. SQLAlchemy-2.0.36.dist-info/top_level.txt +1 -0
  6. sqlalchemy/__init__.py +294 -0
  7. sqlalchemy/connectors/__init__.py +18 -0
  8. sqlalchemy/connectors/aioodbc.py +174 -0
  9. sqlalchemy/connectors/asyncio.py +213 -0
  10. sqlalchemy/connectors/pyodbc.py +249 -0
  11. sqlalchemy/cyextension/__init__.py +6 -0
  12. sqlalchemy/cyextension/collections.cp313-win32.pyd +0 -0
  13. sqlalchemy/cyextension/collections.pyx +409 -0
  14. sqlalchemy/cyextension/immutabledict.cp313-win32.pyd +0 -0
  15. sqlalchemy/cyextension/immutabledict.pxd +8 -0
  16. sqlalchemy/cyextension/immutabledict.pyx +133 -0
  17. sqlalchemy/cyextension/processors.cp313-win32.pyd +0 -0
  18. sqlalchemy/cyextension/processors.pyx +68 -0
  19. sqlalchemy/cyextension/resultproxy.cp313-win32.pyd +0 -0
  20. sqlalchemy/cyextension/resultproxy.pyx +102 -0
  21. sqlalchemy/cyextension/util.cp313-win32.pyd +0 -0
  22. sqlalchemy/cyextension/util.pyx +91 -0
  23. sqlalchemy/dialects/__init__.py +61 -0
  24. sqlalchemy/dialects/_typing.py +25 -0
  25. sqlalchemy/dialects/mssql/__init__.py +88 -0
  26. sqlalchemy/dialects/mssql/aioodbc.py +64 -0
  27. sqlalchemy/dialects/mssql/base.py +4010 -0
  28. sqlalchemy/dialects/mssql/information_schema.py +254 -0
  29. sqlalchemy/dialects/mssql/json.py +133 -0
  30. sqlalchemy/dialects/mssql/provision.py +162 -0
  31. sqlalchemy/dialects/mssql/pymssql.py +126 -0
  32. sqlalchemy/dialects/mssql/pyodbc.py +745 -0
  33. sqlalchemy/dialects/mysql/__init__.py +101 -0
  34. sqlalchemy/dialects/mysql/aiomysql.py +333 -0
  35. sqlalchemy/dialects/mysql/asyncmy.py +337 -0
  36. sqlalchemy/dialects/mysql/base.py +3494 -0
  37. sqlalchemy/dialects/mysql/cymysql.py +84 -0
  38. sqlalchemy/dialects/mysql/dml.py +219 -0
  39. sqlalchemy/dialects/mysql/enumerated.py +244 -0
  40. sqlalchemy/dialects/mysql/expression.py +141 -0
  41. sqlalchemy/dialects/mysql/json.py +81 -0
  42. sqlalchemy/dialects/mysql/mariadb.py +32 -0
  43. sqlalchemy/dialects/mysql/mariadbconnector.py +277 -0
  44. sqlalchemy/dialects/mysql/mysqlconnector.py +180 -0
  45. sqlalchemy/dialects/mysql/mysqldb.py +303 -0
  46. sqlalchemy/dialects/mysql/provision.py +110 -0
  47. sqlalchemy/dialects/mysql/pymysql.py +137 -0
  48. sqlalchemy/dialects/mysql/pyodbc.py +138 -0
  49. sqlalchemy/dialects/mysql/reflection.py +677 -0
  50. sqlalchemy/dialects/mysql/reserved_words.py +571 -0
  51. sqlalchemy/dialects/mysql/types.py +774 -0
  52. sqlalchemy/dialects/oracle/__init__.py +67 -0
  53. sqlalchemy/dialects/oracle/base.py +3271 -0
  54. sqlalchemy/dialects/oracle/cx_oracle.py +1483 -0
  55. sqlalchemy/dialects/oracle/dictionary.py +507 -0
  56. sqlalchemy/dialects/oracle/oracledb.py +431 -0
  57. sqlalchemy/dialects/oracle/provision.py +220 -0
  58. sqlalchemy/dialects/oracle/types.py +287 -0
  59. sqlalchemy/dialects/postgresql/__init__.py +167 -0
  60. sqlalchemy/dialects/postgresql/_psycopg_common.py +187 -0
  61. sqlalchemy/dialects/postgresql/array.py +425 -0
  62. sqlalchemy/dialects/postgresql/asyncpg.py +1274 -0
  63. sqlalchemy/dialects/postgresql/base.py +5008 -0
  64. sqlalchemy/dialects/postgresql/dml.py +310 -0
  65. sqlalchemy/dialects/postgresql/ext.py +496 -0
  66. sqlalchemy/dialects/postgresql/hstore.py +397 -0
  67. sqlalchemy/dialects/postgresql/json.py +333 -0
  68. sqlalchemy/dialects/postgresql/named_types.py +509 -0
  69. sqlalchemy/dialects/postgresql/operators.py +129 -0
  70. sqlalchemy/dialects/postgresql/pg8000.py +662 -0
  71. sqlalchemy/dialects/postgresql/pg_catalog.py +300 -0
  72. sqlalchemy/dialects/postgresql/provision.py +175 -0
  73. sqlalchemy/dialects/postgresql/psycopg.py +772 -0
  74. sqlalchemy/dialects/postgresql/psycopg2.py +886 -0
  75. sqlalchemy/dialects/postgresql/psycopg2cffi.py +61 -0
  76. sqlalchemy/dialects/postgresql/ranges.py +1029 -0
  77. sqlalchemy/dialects/postgresql/types.py +303 -0
  78. sqlalchemy/dialects/sqlite/__init__.py +57 -0
  79. sqlalchemy/dialects/sqlite/aiosqlite.py +396 -0
  80. sqlalchemy/dialects/sqlite/base.py +2805 -0
  81. sqlalchemy/dialects/sqlite/dml.py +240 -0
  82. sqlalchemy/dialects/sqlite/json.py +92 -0
  83. sqlalchemy/dialects/sqlite/provision.py +198 -0
  84. sqlalchemy/dialects/sqlite/pysqlcipher.py +155 -0
  85. sqlalchemy/dialects/sqlite/pysqlite.py +756 -0
  86. sqlalchemy/dialects/type_migration_guidelines.txt +145 -0
  87. sqlalchemy/engine/__init__.py +62 -0
  88. sqlalchemy/engine/_py_processors.py +136 -0
  89. sqlalchemy/engine/_py_row.py +128 -0
  90. sqlalchemy/engine/_py_util.py +74 -0
  91. sqlalchemy/engine/base.py +3375 -0
  92. sqlalchemy/engine/characteristics.py +155 -0
  93. sqlalchemy/engine/create.py +875 -0
  94. sqlalchemy/engine/cursor.py +2181 -0
  95. sqlalchemy/engine/default.py +2365 -0
  96. sqlalchemy/engine/events.py +951 -0
  97. sqlalchemy/engine/interfaces.py +3403 -0
  98. sqlalchemy/engine/mock.py +131 -0
  99. sqlalchemy/engine/processors.py +61 -0
  100. sqlalchemy/engine/reflection.py +2098 -0
  101. sqlalchemy/engine/result.py +2382 -0
  102. sqlalchemy/engine/row.py +401 -0
  103. sqlalchemy/engine/strategies.py +19 -0
  104. sqlalchemy/engine/url.py +910 -0
  105. sqlalchemy/engine/util.py +167 -0
  106. sqlalchemy/event/__init__.py +25 -0
  107. sqlalchemy/event/api.py +225 -0
  108. sqlalchemy/event/attr.py +655 -0
  109. sqlalchemy/event/base.py +470 -0
  110. sqlalchemy/event/legacy.py +246 -0
  111. sqlalchemy/event/registry.py +386 -0
  112. sqlalchemy/events.py +17 -0
  113. sqlalchemy/exc.py +830 -0
  114. sqlalchemy/ext/__init__.py +11 -0
  115. sqlalchemy/ext/associationproxy.py +2013 -0
  116. sqlalchemy/ext/asyncio/__init__.py +25 -0
  117. sqlalchemy/ext/asyncio/base.py +279 -0
  118. sqlalchemy/ext/asyncio/engine.py +1466 -0
  119. sqlalchemy/ext/asyncio/exc.py +21 -0
  120. sqlalchemy/ext/asyncio/result.py +961 -0
  121. sqlalchemy/ext/asyncio/scoping.py +1614 -0
  122. sqlalchemy/ext/asyncio/session.py +1936 -0
  123. sqlalchemy/ext/automap.py +1691 -0
  124. sqlalchemy/ext/baked.py +574 -0
  125. sqlalchemy/ext/compiler.py +570 -0
  126. sqlalchemy/ext/declarative/__init__.py +65 -0
  127. sqlalchemy/ext/declarative/extensions.py +548 -0
  128. sqlalchemy/ext/horizontal_shard.py +481 -0
  129. sqlalchemy/ext/hybrid.py +1514 -0
  130. sqlalchemy/ext/indexable.py +341 -0
  131. sqlalchemy/ext/instrumentation.py +450 -0
  132. sqlalchemy/ext/mutable.py +1073 -0
  133. sqlalchemy/ext/mypy/__init__.py +6 -0
  134. sqlalchemy/ext/mypy/apply.py +320 -0
  135. sqlalchemy/ext/mypy/decl_class.py +515 -0
  136. sqlalchemy/ext/mypy/infer.py +590 -0
  137. sqlalchemy/ext/mypy/names.py +335 -0
  138. sqlalchemy/ext/mypy/plugin.py +303 -0
  139. sqlalchemy/ext/mypy/util.py +357 -0
  140. sqlalchemy/ext/orderinglist.py +416 -0
  141. sqlalchemy/ext/serializer.py +181 -0
  142. sqlalchemy/future/__init__.py +16 -0
  143. sqlalchemy/future/engine.py +15 -0
  144. sqlalchemy/inspection.py +174 -0
  145. sqlalchemy/log.py +288 -0
  146. sqlalchemy/orm/__init__.py +170 -0
  147. sqlalchemy/orm/_orm_constructors.py +2571 -0
  148. sqlalchemy/orm/_typing.py +179 -0
  149. sqlalchemy/orm/attributes.py +2835 -0
  150. sqlalchemy/orm/base.py +973 -0
  151. sqlalchemy/orm/bulk_persistence.py +2123 -0
  152. sqlalchemy/orm/clsregistry.py +571 -0
  153. sqlalchemy/orm/collections.py +1620 -0
  154. sqlalchemy/orm/context.py +3268 -0
  155. sqlalchemy/orm/decl_api.py +1883 -0
  156. sqlalchemy/orm/decl_base.py +2190 -0
  157. sqlalchemy/orm/dependency.py +1304 -0
  158. sqlalchemy/orm/descriptor_props.py +1076 -0
  159. sqlalchemy/orm/dynamic.py +300 -0
  160. sqlalchemy/orm/evaluator.py +379 -0
  161. sqlalchemy/orm/events.py +3261 -0
  162. sqlalchemy/orm/exc.py +228 -0
  163. sqlalchemy/orm/identity.py +302 -0
  164. sqlalchemy/orm/instrumentation.py +754 -0
  165. sqlalchemy/orm/interfaces.py +1474 -0
  166. sqlalchemy/orm/loading.py +1682 -0
  167. sqlalchemy/orm/mapped_collection.py +557 -0
  168. sqlalchemy/orm/mapper.py +4432 -0
  169. sqlalchemy/orm/path_registry.py +811 -0
  170. sqlalchemy/orm/persistence.py +1782 -0
  171. sqlalchemy/orm/properties.py +886 -0
  172. sqlalchemy/orm/query.py +3396 -0
  173. sqlalchemy/orm/relationships.py +3500 -0
  174. sqlalchemy/orm/scoping.py +2165 -0
  175. sqlalchemy/orm/session.py +5301 -0
  176. sqlalchemy/orm/state.py +1143 -0
  177. sqlalchemy/orm/state_changes.py +198 -0
  178. sqlalchemy/orm/strategies.py +3473 -0
  179. sqlalchemy/orm/strategy_options.py +2569 -0
  180. sqlalchemy/orm/sync.py +164 -0
  181. sqlalchemy/orm/unitofwork.py +796 -0
  182. sqlalchemy/orm/util.py +2424 -0
  183. sqlalchemy/orm/writeonly.py +678 -0
  184. sqlalchemy/pool/__init__.py +44 -0
  185. sqlalchemy/pool/base.py +1515 -0
  186. sqlalchemy/pool/events.py +370 -0
  187. sqlalchemy/pool/impl.py +581 -0
  188. sqlalchemy/py.typed +0 -0
  189. sqlalchemy/schema.py +70 -0
  190. sqlalchemy/sql/__init__.py +145 -0
  191. sqlalchemy/sql/_dml_constructors.py +140 -0
  192. sqlalchemy/sql/_elements_constructors.py +1850 -0
  193. sqlalchemy/sql/_orm_types.py +20 -0
  194. sqlalchemy/sql/_py_util.py +75 -0
  195. sqlalchemy/sql/_selectable_constructors.py +635 -0
  196. sqlalchemy/sql/_typing.py +460 -0
  197. sqlalchemy/sql/annotation.py +585 -0
  198. sqlalchemy/sql/base.py +2185 -0
  199. sqlalchemy/sql/cache_key.py +1057 -0
  200. sqlalchemy/sql/coercions.py +1405 -0
  201. sqlalchemy/sql/compiler.py +7818 -0
  202. sqlalchemy/sql/crud.py +1669 -0
  203. sqlalchemy/sql/ddl.py +1378 -0
  204. sqlalchemy/sql/default_comparator.py +552 -0
  205. sqlalchemy/sql/dml.py +1817 -0
  206. sqlalchemy/sql/elements.py +5499 -0
  207. sqlalchemy/sql/events.py +455 -0
  208. sqlalchemy/sql/expression.py +162 -0
  209. sqlalchemy/sql/functions.py +2055 -0
  210. sqlalchemy/sql/lambdas.py +1449 -0
  211. sqlalchemy/sql/naming.py +212 -0
  212. sqlalchemy/sql/operators.py +2579 -0
  213. sqlalchemy/sql/roles.py +323 -0
  214. sqlalchemy/sql/schema.py +6158 -0
  215. sqlalchemy/sql/selectable.py +7004 -0
  216. sqlalchemy/sql/sqltypes.py +3827 -0
  217. sqlalchemy/sql/traversals.py +1024 -0
  218. sqlalchemy/sql/type_api.py +2339 -0
  219. sqlalchemy/sql/util.py +1486 -0
  220. sqlalchemy/sql/visitors.py +1165 -0
  221. sqlalchemy/testing/__init__.py +96 -0
  222. sqlalchemy/testing/assertions.py +989 -0
  223. sqlalchemy/testing/assertsql.py +516 -0
  224. sqlalchemy/testing/asyncio.py +135 -0
  225. sqlalchemy/testing/config.py +427 -0
  226. sqlalchemy/testing/engines.py +472 -0
  227. sqlalchemy/testing/entities.py +117 -0
  228. sqlalchemy/testing/exclusions.py +435 -0
  229. sqlalchemy/testing/fixtures/__init__.py +28 -0
  230. sqlalchemy/testing/fixtures/base.py +366 -0
  231. sqlalchemy/testing/fixtures/mypy.py +312 -0
  232. sqlalchemy/testing/fixtures/orm.py +227 -0
  233. sqlalchemy/testing/fixtures/sql.py +503 -0
  234. sqlalchemy/testing/pickleable.py +155 -0
  235. sqlalchemy/testing/plugin/__init__.py +6 -0
  236. sqlalchemy/testing/plugin/bootstrap.py +51 -0
  237. sqlalchemy/testing/plugin/plugin_base.py +779 -0
  238. sqlalchemy/testing/plugin/pytestplugin.py +868 -0
  239. sqlalchemy/testing/profiling.py +324 -0
  240. sqlalchemy/testing/provision.py +496 -0
  241. sqlalchemy/testing/requirements.py +1818 -0
  242. sqlalchemy/testing/schema.py +224 -0
  243. sqlalchemy/testing/suite/__init__.py +19 -0
  244. sqlalchemy/testing/suite/test_cte.py +211 -0
  245. sqlalchemy/testing/suite/test_ddl.py +389 -0
  246. sqlalchemy/testing/suite/test_deprecations.py +153 -0
  247. sqlalchemy/testing/suite/test_dialect.py +740 -0
  248. sqlalchemy/testing/suite/test_insert.py +630 -0
  249. sqlalchemy/testing/suite/test_reflection.py +3225 -0
  250. sqlalchemy/testing/suite/test_results.py +502 -0
  251. sqlalchemy/testing/suite/test_rowcount.py +258 -0
  252. sqlalchemy/testing/suite/test_select.py +1999 -0
  253. sqlalchemy/testing/suite/test_sequence.py +317 -0
  254. sqlalchemy/testing/suite/test_types.py +2141 -0
  255. sqlalchemy/testing/suite/test_unicode_ddl.py +189 -0
  256. sqlalchemy/testing/suite/test_update_delete.py +139 -0
  257. sqlalchemy/testing/util.py +537 -0
  258. sqlalchemy/testing/warnings.py +52 -0
  259. sqlalchemy/types.py +76 -0
  260. sqlalchemy/util/__init__.py +160 -0
  261. sqlalchemy/util/_collections.py +715 -0
  262. sqlalchemy/util/_concurrency_py3k.py +288 -0
  263. sqlalchemy/util/_has_cy.py +40 -0
  264. sqlalchemy/util/_py_collections.py +541 -0
  265. sqlalchemy/util/compat.py +301 -0
  266. sqlalchemy/util/concurrency.py +108 -0
  267. sqlalchemy/util/deprecations.py +401 -0
  268. sqlalchemy/util/langhelpers.py +2218 -0
  269. sqlalchemy/util/preloaded.py +150 -0
  270. sqlalchemy/util/queue.py +322 -0
  271. sqlalchemy/util/tool_support.py +201 -0
  272. sqlalchemy/util/topological.py +120 -0
  273. sqlalchemy/util/typing.py +629 -0
@@ -0,0 +1,581 @@
1
+ # pool/impl.py
2
+ # Copyright (C) 2005-2024 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
+
8
+
9
+ """Pool implementation classes.
10
+
11
+ """
12
+ from __future__ import annotations
13
+
14
+ import threading
15
+ import traceback
16
+ import typing
17
+ from typing import Any
18
+ from typing import cast
19
+ from typing import List
20
+ from typing import Optional
21
+ from typing import Set
22
+ from typing import Type
23
+ from typing import TYPE_CHECKING
24
+ from typing import Union
25
+ import weakref
26
+
27
+ from .base import _AsyncConnDialect
28
+ from .base import _ConnectionFairy
29
+ from .base import _ConnectionRecord
30
+ from .base import _CreatorFnType
31
+ from .base import _CreatorWRecFnType
32
+ from .base import ConnectionPoolEntry
33
+ from .base import Pool
34
+ from .base import PoolProxiedConnection
35
+ from .. import exc
36
+ from .. import util
37
+ from ..util import chop_traceback
38
+ from ..util import queue as sqla_queue
39
+ from ..util.typing import Literal
40
+
41
+ if typing.TYPE_CHECKING:
42
+ from ..engine.interfaces import DBAPIConnection
43
+
44
+
45
+ class QueuePool(Pool):
46
+ """A :class:`_pool.Pool`
47
+ that imposes a limit on the number of open connections.
48
+
49
+ :class:`.QueuePool` is the default pooling implementation used for
50
+ all :class:`_engine.Engine` objects other than SQLite with a ``:memory:``
51
+ database.
52
+
53
+ The :class:`.QueuePool` class **is not compatible** with asyncio and
54
+ :func:`_asyncio.create_async_engine`. The
55
+ :class:`.AsyncAdaptedQueuePool` class is used automatically when
56
+ using :func:`_asyncio.create_async_engine`, if no other kind of pool
57
+ is specified.
58
+
59
+ .. seealso::
60
+
61
+ :class:`.AsyncAdaptedQueuePool`
62
+
63
+ """
64
+
65
+ _is_asyncio = False # type: ignore[assignment]
66
+
67
+ _queue_class: Type[sqla_queue.QueueCommon[ConnectionPoolEntry]] = (
68
+ sqla_queue.Queue
69
+ )
70
+
71
+ _pool: sqla_queue.QueueCommon[ConnectionPoolEntry]
72
+
73
+ def __init__(
74
+ self,
75
+ creator: Union[_CreatorFnType, _CreatorWRecFnType],
76
+ pool_size: int = 5,
77
+ max_overflow: int = 10,
78
+ timeout: float = 30.0,
79
+ use_lifo: bool = False,
80
+ **kw: Any,
81
+ ):
82
+ r"""
83
+ Construct a QueuePool.
84
+
85
+ :param creator: a callable function that returns a DB-API
86
+ connection object, same as that of :paramref:`_pool.Pool.creator`.
87
+
88
+ :param pool_size: The size of the pool to be maintained,
89
+ defaults to 5. This is the largest number of connections that
90
+ will be kept persistently in the pool. Note that the pool
91
+ begins with no connections; once this number of connections
92
+ is requested, that number of connections will remain.
93
+ ``pool_size`` can be set to 0 to indicate no size limit; to
94
+ disable pooling, use a :class:`~sqlalchemy.pool.NullPool`
95
+ instead.
96
+
97
+ :param max_overflow: The maximum overflow size of the
98
+ pool. When the number of checked-out connections reaches the
99
+ size set in pool_size, additional connections will be
100
+ returned up to this limit. When those additional connections
101
+ are returned to the pool, they are disconnected and
102
+ discarded. It follows then that the total number of
103
+ simultaneous connections the pool will allow is pool_size +
104
+ `max_overflow`, and the total number of "sleeping"
105
+ connections the pool will allow is pool_size. `max_overflow`
106
+ can be set to -1 to indicate no overflow limit; no limit
107
+ will be placed on the total number of concurrent
108
+ connections. Defaults to 10.
109
+
110
+ :param timeout: The number of seconds to wait before giving up
111
+ on returning a connection. Defaults to 30.0. This can be a float
112
+ but is subject to the limitations of Python time functions which
113
+ may not be reliable in the tens of milliseconds.
114
+
115
+ :param use_lifo: use LIFO (last-in-first-out) when retrieving
116
+ connections instead of FIFO (first-in-first-out). Using LIFO, a
117
+ server-side timeout scheme can reduce the number of connections used
118
+ during non-peak periods of use. When planning for server-side
119
+ timeouts, ensure that a recycle or pre-ping strategy is in use to
120
+ gracefully handle stale connections.
121
+
122
+ .. versionadded:: 1.3
123
+
124
+ .. seealso::
125
+
126
+ :ref:`pool_use_lifo`
127
+
128
+ :ref:`pool_disconnects`
129
+
130
+ :param \**kw: Other keyword arguments including
131
+ :paramref:`_pool.Pool.recycle`, :paramref:`_pool.Pool.echo`,
132
+ :paramref:`_pool.Pool.reset_on_return` and others are passed to the
133
+ :class:`_pool.Pool` constructor.
134
+
135
+ """
136
+
137
+ Pool.__init__(self, creator, **kw)
138
+ self._pool = self._queue_class(pool_size, use_lifo=use_lifo)
139
+ self._overflow = 0 - pool_size
140
+ self._max_overflow = -1 if pool_size == 0 else max_overflow
141
+ self._timeout = timeout
142
+ self._overflow_lock = threading.Lock()
143
+
144
+ def _do_return_conn(self, record: ConnectionPoolEntry) -> None:
145
+ try:
146
+ self._pool.put(record, False)
147
+ except sqla_queue.Full:
148
+ try:
149
+ record.close()
150
+ finally:
151
+ self._dec_overflow()
152
+
153
+ def _do_get(self) -> ConnectionPoolEntry:
154
+ use_overflow = self._max_overflow > -1
155
+
156
+ wait = use_overflow and self._overflow >= self._max_overflow
157
+ try:
158
+ return self._pool.get(wait, self._timeout)
159
+ except sqla_queue.Empty:
160
+ # don't do things inside of "except Empty", because when we say
161
+ # we timed out or can't connect and raise, Python 3 tells
162
+ # people the real error is queue.Empty which it isn't.
163
+ pass
164
+ if use_overflow and self._overflow >= self._max_overflow:
165
+ if not wait:
166
+ return self._do_get()
167
+ else:
168
+ raise exc.TimeoutError(
169
+ "QueuePool limit of size %d overflow %d reached, "
170
+ "connection timed out, timeout %0.2f"
171
+ % (self.size(), self.overflow(), self._timeout),
172
+ code="3o7r",
173
+ )
174
+
175
+ if self._inc_overflow():
176
+ try:
177
+ return self._create_connection()
178
+ except:
179
+ with util.safe_reraise():
180
+ self._dec_overflow()
181
+ raise
182
+ else:
183
+ return self._do_get()
184
+
185
+ def _inc_overflow(self) -> bool:
186
+ if self._max_overflow == -1:
187
+ self._overflow += 1
188
+ return True
189
+ with self._overflow_lock:
190
+ if self._overflow < self._max_overflow:
191
+ self._overflow += 1
192
+ return True
193
+ else:
194
+ return False
195
+
196
+ def _dec_overflow(self) -> Literal[True]:
197
+ if self._max_overflow == -1:
198
+ self._overflow -= 1
199
+ return True
200
+ with self._overflow_lock:
201
+ self._overflow -= 1
202
+ return True
203
+
204
+ def recreate(self) -> QueuePool:
205
+ self.logger.info("Pool recreating")
206
+ return self.__class__(
207
+ self._creator,
208
+ pool_size=self._pool.maxsize,
209
+ max_overflow=self._max_overflow,
210
+ pre_ping=self._pre_ping,
211
+ use_lifo=self._pool.use_lifo,
212
+ timeout=self._timeout,
213
+ recycle=self._recycle,
214
+ echo=self.echo,
215
+ logging_name=self._orig_logging_name,
216
+ reset_on_return=self._reset_on_return,
217
+ _dispatch=self.dispatch,
218
+ dialect=self._dialect,
219
+ )
220
+
221
+ def dispose(self) -> None:
222
+ while True:
223
+ try:
224
+ conn = self._pool.get(False)
225
+ conn.close()
226
+ except sqla_queue.Empty:
227
+ break
228
+
229
+ self._overflow = 0 - self.size()
230
+ self.logger.info("Pool disposed. %s", self.status())
231
+
232
+ def status(self) -> str:
233
+ return (
234
+ "Pool size: %d Connections in pool: %d "
235
+ "Current Overflow: %d Current Checked out "
236
+ "connections: %d"
237
+ % (
238
+ self.size(),
239
+ self.checkedin(),
240
+ self.overflow(),
241
+ self.checkedout(),
242
+ )
243
+ )
244
+
245
+ def size(self) -> int:
246
+ return self._pool.maxsize
247
+
248
+ def timeout(self) -> float:
249
+ return self._timeout
250
+
251
+ def checkedin(self) -> int:
252
+ return self._pool.qsize()
253
+
254
+ def overflow(self) -> int:
255
+ return self._overflow if self._pool.maxsize else 0
256
+
257
+ def checkedout(self) -> int:
258
+ return self._pool.maxsize - self._pool.qsize() + self._overflow
259
+
260
+
261
+ class AsyncAdaptedQueuePool(QueuePool):
262
+ """An asyncio-compatible version of :class:`.QueuePool`.
263
+
264
+ This pool is used by default when using :class:`.AsyncEngine` engines that
265
+ were generated from :func:`_asyncio.create_async_engine`. It uses an
266
+ asyncio-compatible queue implementation that does not use
267
+ ``threading.Lock``.
268
+
269
+ The arguments and operation of :class:`.AsyncAdaptedQueuePool` are
270
+ otherwise identical to that of :class:`.QueuePool`.
271
+
272
+ """
273
+
274
+ _is_asyncio = True # type: ignore[assignment]
275
+ _queue_class: Type[sqla_queue.QueueCommon[ConnectionPoolEntry]] = (
276
+ sqla_queue.AsyncAdaptedQueue
277
+ )
278
+
279
+ _dialect = _AsyncConnDialect()
280
+
281
+
282
+ class FallbackAsyncAdaptedQueuePool(AsyncAdaptedQueuePool):
283
+ _queue_class = sqla_queue.FallbackAsyncAdaptedQueue
284
+
285
+
286
+ class NullPool(Pool):
287
+ """A Pool which does not pool connections.
288
+
289
+ Instead it literally opens and closes the underlying DB-API connection
290
+ per each connection open/close.
291
+
292
+ Reconnect-related functions such as ``recycle`` and connection
293
+ invalidation are not supported by this Pool implementation, since
294
+ no connections are held persistently.
295
+
296
+ The :class:`.NullPool` class **is compatible** with asyncio and
297
+ :func:`_asyncio.create_async_engine`.
298
+
299
+ """
300
+
301
+ def status(self) -> str:
302
+ return "NullPool"
303
+
304
+ def _do_return_conn(self, record: ConnectionPoolEntry) -> None:
305
+ record.close()
306
+
307
+ def _do_get(self) -> ConnectionPoolEntry:
308
+ return self._create_connection()
309
+
310
+ def recreate(self) -> NullPool:
311
+ self.logger.info("Pool recreating")
312
+
313
+ return self.__class__(
314
+ self._creator,
315
+ recycle=self._recycle,
316
+ echo=self.echo,
317
+ logging_name=self._orig_logging_name,
318
+ reset_on_return=self._reset_on_return,
319
+ pre_ping=self._pre_ping,
320
+ _dispatch=self.dispatch,
321
+ dialect=self._dialect,
322
+ )
323
+
324
+ def dispose(self) -> None:
325
+ pass
326
+
327
+
328
+ class SingletonThreadPool(Pool):
329
+ """A Pool that maintains one connection per thread.
330
+
331
+ Maintains one connection per each thread, never moving a connection to a
332
+ thread other than the one which it was created in.
333
+
334
+ .. warning:: the :class:`.SingletonThreadPool` will call ``.close()``
335
+ on arbitrary connections that exist beyond the size setting of
336
+ ``pool_size``, e.g. if more unique **thread identities**
337
+ than what ``pool_size`` states are used. This cleanup is
338
+ non-deterministic and not sensitive to whether or not the connections
339
+ linked to those thread identities are currently in use.
340
+
341
+ :class:`.SingletonThreadPool` may be improved in a future release,
342
+ however in its current status it is generally used only for test
343
+ scenarios using a SQLite ``:memory:`` database and is not recommended
344
+ for production use.
345
+
346
+ The :class:`.SingletonThreadPool` class **is not compatible** with asyncio
347
+ and :func:`_asyncio.create_async_engine`.
348
+
349
+
350
+ Options are the same as those of :class:`_pool.Pool`, as well as:
351
+
352
+ :param pool_size: The number of threads in which to maintain connections
353
+ at once. Defaults to five.
354
+
355
+ :class:`.SingletonThreadPool` is used by the SQLite dialect
356
+ automatically when a memory-based database is used.
357
+ See :ref:`sqlite_toplevel`.
358
+
359
+ """
360
+
361
+ _is_asyncio = False # type: ignore[assignment]
362
+
363
+ def __init__(
364
+ self,
365
+ creator: Union[_CreatorFnType, _CreatorWRecFnType],
366
+ pool_size: int = 5,
367
+ **kw: Any,
368
+ ):
369
+ Pool.__init__(self, creator, **kw)
370
+ self._conn = threading.local()
371
+ self._fairy = threading.local()
372
+ self._all_conns: Set[ConnectionPoolEntry] = set()
373
+ self.size = pool_size
374
+
375
+ def recreate(self) -> SingletonThreadPool:
376
+ self.logger.info("Pool recreating")
377
+ return self.__class__(
378
+ self._creator,
379
+ pool_size=self.size,
380
+ recycle=self._recycle,
381
+ echo=self.echo,
382
+ pre_ping=self._pre_ping,
383
+ logging_name=self._orig_logging_name,
384
+ reset_on_return=self._reset_on_return,
385
+ _dispatch=self.dispatch,
386
+ dialect=self._dialect,
387
+ )
388
+
389
+ def dispose(self) -> None:
390
+ """Dispose of this pool."""
391
+
392
+ for conn in self._all_conns:
393
+ try:
394
+ conn.close()
395
+ except Exception:
396
+ # pysqlite won't even let you close a conn from a thread
397
+ # that didn't create it
398
+ pass
399
+
400
+ self._all_conns.clear()
401
+
402
+ def _cleanup(self) -> None:
403
+ while len(self._all_conns) >= self.size:
404
+ c = self._all_conns.pop()
405
+ c.close()
406
+
407
+ def status(self) -> str:
408
+ return "SingletonThreadPool id:%d size: %d" % (
409
+ id(self),
410
+ len(self._all_conns),
411
+ )
412
+
413
+ def _do_return_conn(self, record: ConnectionPoolEntry) -> None:
414
+ try:
415
+ del self._fairy.current
416
+ except AttributeError:
417
+ pass
418
+
419
+ def _do_get(self) -> ConnectionPoolEntry:
420
+ try:
421
+ if TYPE_CHECKING:
422
+ c = cast(ConnectionPoolEntry, self._conn.current())
423
+ else:
424
+ c = self._conn.current()
425
+ if c:
426
+ return c
427
+ except AttributeError:
428
+ pass
429
+ c = self._create_connection()
430
+ self._conn.current = weakref.ref(c)
431
+ if len(self._all_conns) >= self.size:
432
+ self._cleanup()
433
+ self._all_conns.add(c)
434
+ return c
435
+
436
+ def connect(self) -> PoolProxiedConnection:
437
+ # vendored from Pool to include the now removed use_threadlocal
438
+ # behavior
439
+ try:
440
+ rec = cast(_ConnectionFairy, self._fairy.current())
441
+ except AttributeError:
442
+ pass
443
+ else:
444
+ if rec is not None:
445
+ return rec._checkout_existing()
446
+
447
+ return _ConnectionFairy._checkout(self, self._fairy)
448
+
449
+
450
+ class StaticPool(Pool):
451
+ """A Pool of exactly one connection, used for all requests.
452
+
453
+ Reconnect-related functions such as ``recycle`` and connection
454
+ invalidation (which is also used to support auto-reconnect) are only
455
+ partially supported right now and may not yield good results.
456
+
457
+ The :class:`.StaticPool` class **is compatible** with asyncio and
458
+ :func:`_asyncio.create_async_engine`.
459
+
460
+ """
461
+
462
+ @util.memoized_property
463
+ def connection(self) -> _ConnectionRecord:
464
+ return _ConnectionRecord(self)
465
+
466
+ def status(self) -> str:
467
+ return "StaticPool"
468
+
469
+ def dispose(self) -> None:
470
+ if (
471
+ "connection" in self.__dict__
472
+ and self.connection.dbapi_connection is not None
473
+ ):
474
+ self.connection.close()
475
+ del self.__dict__["connection"]
476
+
477
+ def recreate(self) -> StaticPool:
478
+ self.logger.info("Pool recreating")
479
+ return self.__class__(
480
+ creator=self._creator,
481
+ recycle=self._recycle,
482
+ reset_on_return=self._reset_on_return,
483
+ pre_ping=self._pre_ping,
484
+ echo=self.echo,
485
+ logging_name=self._orig_logging_name,
486
+ _dispatch=self.dispatch,
487
+ dialect=self._dialect,
488
+ )
489
+
490
+ def _transfer_from(self, other_static_pool: StaticPool) -> None:
491
+ # used by the test suite to make a new engine / pool without
492
+ # losing the state of an existing SQLite :memory: connection
493
+ def creator(rec: ConnectionPoolEntry) -> DBAPIConnection:
494
+ conn = other_static_pool.connection.dbapi_connection
495
+ assert conn is not None
496
+ return conn
497
+
498
+ self._invoke_creator = creator
499
+
500
+ def _create_connection(self) -> ConnectionPoolEntry:
501
+ raise NotImplementedError()
502
+
503
+ def _do_return_conn(self, record: ConnectionPoolEntry) -> None:
504
+ pass
505
+
506
+ def _do_get(self) -> ConnectionPoolEntry:
507
+ rec = self.connection
508
+ if rec._is_hard_or_soft_invalidated():
509
+ del self.__dict__["connection"]
510
+ rec = self.connection
511
+
512
+ return rec
513
+
514
+
515
+ class AssertionPool(Pool):
516
+ """A :class:`_pool.Pool` that allows at most one checked out connection at
517
+ any given time.
518
+
519
+ This will raise an exception if more than one connection is checked out
520
+ at a time. Useful for debugging code that is using more connections
521
+ than desired.
522
+
523
+ The :class:`.AssertionPool` class **is compatible** with asyncio and
524
+ :func:`_asyncio.create_async_engine`.
525
+
526
+ """
527
+
528
+ _conn: Optional[ConnectionPoolEntry]
529
+ _checkout_traceback: Optional[List[str]]
530
+
531
+ def __init__(self, *args: Any, **kw: Any):
532
+ self._conn = None
533
+ self._checked_out = False
534
+ self._store_traceback = kw.pop("store_traceback", True)
535
+ self._checkout_traceback = None
536
+ Pool.__init__(self, *args, **kw)
537
+
538
+ def status(self) -> str:
539
+ return "AssertionPool"
540
+
541
+ def _do_return_conn(self, record: ConnectionPoolEntry) -> None:
542
+ if not self._checked_out:
543
+ raise AssertionError("connection is not checked out")
544
+ self._checked_out = False
545
+ assert record is self._conn
546
+
547
+ def dispose(self) -> None:
548
+ self._checked_out = False
549
+ if self._conn:
550
+ self._conn.close()
551
+
552
+ def recreate(self) -> AssertionPool:
553
+ self.logger.info("Pool recreating")
554
+ return self.__class__(
555
+ self._creator,
556
+ echo=self.echo,
557
+ pre_ping=self._pre_ping,
558
+ recycle=self._recycle,
559
+ reset_on_return=self._reset_on_return,
560
+ logging_name=self._orig_logging_name,
561
+ _dispatch=self.dispatch,
562
+ dialect=self._dialect,
563
+ )
564
+
565
+ def _do_get(self) -> ConnectionPoolEntry:
566
+ if self._checked_out:
567
+ if self._checkout_traceback:
568
+ suffix = " at:\n%s" % "".join(
569
+ chop_traceback(self._checkout_traceback)
570
+ )
571
+ else:
572
+ suffix = ""
573
+ raise AssertionError("connection is already checked out" + suffix)
574
+
575
+ if not self._conn:
576
+ self._conn = self._create_connection()
577
+
578
+ self._checked_out = True
579
+ if self._store_traceback:
580
+ self._checkout_traceback = traceback.format_stack()
581
+ return self._conn
sqlalchemy/py.typed ADDED
File without changes
sqlalchemy/schema.py ADDED
@@ -0,0 +1,70 @@
1
+ # schema.py
2
+ # Copyright (C) 2005-2024 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
+
8
+ """Compatibility namespace for sqlalchemy.sql.schema and related.
9
+
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ from .sql.base import SchemaVisitor as SchemaVisitor
15
+ from .sql.ddl import _CreateDropBase as _CreateDropBase
16
+ from .sql.ddl import _DropView as _DropView
17
+ from .sql.ddl import AddConstraint as AddConstraint
18
+ from .sql.ddl import BaseDDLElement as BaseDDLElement
19
+ from .sql.ddl import CreateColumn as CreateColumn
20
+ from .sql.ddl import CreateIndex as CreateIndex
21
+ from .sql.ddl import CreateSchema as CreateSchema
22
+ from .sql.ddl import CreateSequence as CreateSequence
23
+ from .sql.ddl import CreateTable as CreateTable
24
+ from .sql.ddl import DDL as DDL
25
+ from .sql.ddl import DDLElement as DDLElement
26
+ from .sql.ddl import DropColumnComment as DropColumnComment
27
+ from .sql.ddl import DropConstraint as DropConstraint
28
+ from .sql.ddl import DropConstraintComment as DropConstraintComment
29
+ from .sql.ddl import DropIndex as DropIndex
30
+ from .sql.ddl import DropSchema as DropSchema
31
+ from .sql.ddl import DropSequence as DropSequence
32
+ from .sql.ddl import DropTable as DropTable
33
+ from .sql.ddl import DropTableComment as DropTableComment
34
+ from .sql.ddl import ExecutableDDLElement as ExecutableDDLElement
35
+ from .sql.ddl import InvokeDDLBase as InvokeDDLBase
36
+ from .sql.ddl import SetColumnComment as SetColumnComment
37
+ from .sql.ddl import SetConstraintComment as SetConstraintComment
38
+ from .sql.ddl import SetTableComment as SetTableComment
39
+ from .sql.ddl import sort_tables as sort_tables
40
+ from .sql.ddl import (
41
+ sort_tables_and_constraints as sort_tables_and_constraints,
42
+ )
43
+ from .sql.naming import conv as conv
44
+ from .sql.schema import _get_table_key as _get_table_key
45
+ from .sql.schema import BLANK_SCHEMA as BLANK_SCHEMA
46
+ from .sql.schema import CheckConstraint as CheckConstraint
47
+ from .sql.schema import Column as Column
48
+ from .sql.schema import (
49
+ ColumnCollectionConstraint as ColumnCollectionConstraint,
50
+ )
51
+ from .sql.schema import ColumnCollectionMixin as ColumnCollectionMixin
52
+ from .sql.schema import ColumnDefault as ColumnDefault
53
+ from .sql.schema import Computed as Computed
54
+ from .sql.schema import Constraint as Constraint
55
+ from .sql.schema import DefaultClause as DefaultClause
56
+ from .sql.schema import DefaultGenerator as DefaultGenerator
57
+ from .sql.schema import FetchedValue as FetchedValue
58
+ from .sql.schema import ForeignKey as ForeignKey
59
+ from .sql.schema import ForeignKeyConstraint as ForeignKeyConstraint
60
+ from .sql.schema import HasConditionalDDL as HasConditionalDDL
61
+ from .sql.schema import Identity as Identity
62
+ from .sql.schema import Index as Index
63
+ from .sql.schema import insert_sentinel as insert_sentinel
64
+ from .sql.schema import MetaData as MetaData
65
+ from .sql.schema import PrimaryKeyConstraint as PrimaryKeyConstraint
66
+ from .sql.schema import SchemaConst as SchemaConst
67
+ from .sql.schema import SchemaItem as SchemaItem
68
+ from .sql.schema import Sequence as Sequence
69
+ from .sql.schema import Table as Table
70
+ from .sql.schema import UniqueConstraint as UniqueConstraint