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