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