This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
# sqlalchemy/pool/__init__.py
|
||||
# Copyright (C) 2005-2023 the SQLAlchemy authors and contributors
|
||||
# pool/__init__.py
|
||||
# Copyright (C) 2005-2025 the SQLAlchemy authors and contributors
|
||||
# <see AUTHORS file>
|
||||
#
|
||||
# This module is part of SQLAlchemy and is released under
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
# sqlalchemy/pool.py
|
||||
# Copyright (C) 2005-2023 the SQLAlchemy authors and contributors
|
||||
# pool/base.py
|
||||
# Copyright (C) 2005-2025 the SQLAlchemy authors and contributors
|
||||
# <see AUTHORS file>
|
||||
#
|
||||
# This module is part of SQLAlchemy and is released under
|
||||
# the MIT License: https://www.opensource.org/licenses/mit-license.php
|
||||
|
||||
|
||||
"""Base constructs for connection pools.
|
||||
|
||||
"""
|
||||
"""Base constructs for connection pools."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -147,17 +145,14 @@ class _AsyncConnDialect(_ConnDialect):
|
||||
|
||||
|
||||
class _CreatorFnType(Protocol):
|
||||
def __call__(self) -> DBAPIConnection:
|
||||
...
|
||||
def __call__(self) -> DBAPIConnection: ...
|
||||
|
||||
|
||||
class _CreatorWRecFnType(Protocol):
|
||||
def __call__(self, rec: ConnectionPoolEntry) -> DBAPIConnection:
|
||||
...
|
||||
def __call__(self, rec: ConnectionPoolEntry) -> DBAPIConnection: ...
|
||||
|
||||
|
||||
class Pool(log.Identified, event.EventTarget):
|
||||
|
||||
"""Abstract base class for connection pools."""
|
||||
|
||||
dispatch: dispatcher[Pool]
|
||||
@@ -471,6 +466,7 @@ class Pool(log.Identified, event.EventTarget):
|
||||
raise NotImplementedError()
|
||||
|
||||
def status(self) -> str:
|
||||
"""Returns a brief description of the state of this pool."""
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
@@ -633,7 +629,6 @@ class ConnectionPoolEntry(ManagesConnection):
|
||||
|
||||
|
||||
class _ConnectionRecord(ConnectionPoolEntry):
|
||||
|
||||
"""Maintains a position in a connection pool which references a pooled
|
||||
connection.
|
||||
|
||||
@@ -729,11 +724,13 @@ class _ConnectionRecord(ConnectionPoolEntry):
|
||||
|
||||
rec.fairy_ref = ref = weakref.ref(
|
||||
fairy,
|
||||
lambda ref: _finalize_fairy(
|
||||
None, rec, pool, ref, echo, transaction_was_reset=False
|
||||
)
|
||||
if _finalize_fairy is not None
|
||||
else None,
|
||||
lambda ref: (
|
||||
_finalize_fairy(
|
||||
None, rec, pool, ref, echo, transaction_was_reset=False
|
||||
)
|
||||
if _finalize_fairy is not None
|
||||
else None
|
||||
),
|
||||
)
|
||||
_strong_ref_connection_records[ref] = rec
|
||||
if echo:
|
||||
@@ -1074,14 +1071,13 @@ class PoolProxiedConnection(ManagesConnection):
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
|
||||
def commit(self) -> None:
|
||||
...
|
||||
def commit(self) -> None: ...
|
||||
|
||||
def cursor(self) -> DBAPICursor:
|
||||
...
|
||||
def cursor(self, *args: Any, **kwargs: Any) -> DBAPICursor: ...
|
||||
|
||||
def rollback(self) -> None:
|
||||
...
|
||||
def rollback(self) -> None: ...
|
||||
|
||||
def __getattr__(self, key: str) -> Any: ...
|
||||
|
||||
@property
|
||||
def is_valid(self) -> bool:
|
||||
@@ -1189,7 +1185,6 @@ class _AdhocProxiedConnection(PoolProxiedConnection):
|
||||
|
||||
|
||||
class _ConnectionFairy(PoolProxiedConnection):
|
||||
|
||||
"""Proxies a DBAPI connection and provides return-on-dereference
|
||||
support.
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# sqlalchemy/pool/events.py
|
||||
# Copyright (C) 2005-2023 the SQLAlchemy authors and contributors
|
||||
# pool/events.py
|
||||
# Copyright (C) 2005-2025 the SQLAlchemy authors and contributors
|
||||
# <see AUTHORS file>
|
||||
#
|
||||
# This module is part of SQLAlchemy and is released under
|
||||
@@ -35,10 +35,12 @@ class PoolEvents(event.Events[Pool]):
|
||||
|
||||
from sqlalchemy import event
|
||||
|
||||
|
||||
def my_on_checkout(dbapi_conn, connection_rec, connection_proxy):
|
||||
"handle an on checkout event"
|
||||
|
||||
event.listen(Pool, 'checkout', my_on_checkout)
|
||||
|
||||
event.listen(Pool, "checkout", my_on_checkout)
|
||||
|
||||
In addition to accepting the :class:`_pool.Pool` class and
|
||||
:class:`_pool.Pool` instances, :class:`_events.PoolEvents` also accepts
|
||||
@@ -49,7 +51,7 @@ class PoolEvents(event.Events[Pool]):
|
||||
engine = create_engine("postgresql+psycopg2://scott:tiger@localhost/test")
|
||||
|
||||
# will associate with engine.pool
|
||||
event.listen(engine, 'checkout', my_on_checkout)
|
||||
event.listen(engine, "checkout", my_on_checkout)
|
||||
|
||||
""" # noqa: E501
|
||||
|
||||
@@ -173,7 +175,7 @@ class PoolEvents(event.Events[Pool]):
|
||||
|
||||
def checkin(
|
||||
self,
|
||||
dbapi_connection: DBAPIConnection,
|
||||
dbapi_connection: Optional[DBAPIConnection],
|
||||
connection_record: ConnectionPoolEntry,
|
||||
) -> None:
|
||||
"""Called when a connection returns to the pool.
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
# sqlalchemy/pool.py
|
||||
# Copyright (C) 2005-2023 the SQLAlchemy authors and contributors
|
||||
# pool/impl.py
|
||||
# Copyright (C) 2005-2025 the SQLAlchemy authors and contributors
|
||||
# <see AUTHORS file>
|
||||
#
|
||||
# This module is part of SQLAlchemy and is released under
|
||||
# the MIT License: https://www.opensource.org/licenses/mit-license.php
|
||||
|
||||
|
||||
"""Pool implementation classes.
|
||||
|
||||
"""
|
||||
"""Pool implementation classes."""
|
||||
from __future__ import annotations
|
||||
|
||||
import threading
|
||||
@@ -43,21 +41,30 @@ if typing.TYPE_CHECKING:
|
||||
|
||||
|
||||
class QueuePool(Pool):
|
||||
|
||||
"""A :class:`_pool.Pool`
|
||||
that imposes a limit on the number of open connections.
|
||||
|
||||
:class:`.QueuePool` is the default pooling implementation used for
|
||||
all :class:`_engine.Engine` objects, unless the SQLite dialect is
|
||||
in use with a ``:memory:`` database.
|
||||
all :class:`_engine.Engine` objects other than SQLite with a ``:memory:``
|
||||
database.
|
||||
|
||||
The :class:`.QueuePool` class **is not compatible** with asyncio and
|
||||
:func:`_asyncio.create_async_engine`. The
|
||||
:class:`.AsyncAdaptedQueuePool` class is used automatically when
|
||||
using :func:`_asyncio.create_async_engine`, if no other kind of pool
|
||||
is specified.
|
||||
|
||||
.. seealso::
|
||||
|
||||
:class:`.AsyncAdaptedQueuePool`
|
||||
|
||||
"""
|
||||
|
||||
_is_asyncio = False # type: ignore[assignment]
|
||||
_is_asyncio = False
|
||||
|
||||
_queue_class: Type[
|
||||
sqla_queue.QueueCommon[ConnectionPoolEntry]
|
||||
] = sqla_queue.Queue
|
||||
_queue_class: Type[sqla_queue.QueueCommon[ConnectionPoolEntry]] = (
|
||||
sqla_queue.Queue
|
||||
)
|
||||
|
||||
_pool: sqla_queue.QueueCommon[ConnectionPoolEntry]
|
||||
|
||||
@@ -124,6 +131,7 @@ class QueuePool(Pool):
|
||||
:class:`_pool.Pool` constructor.
|
||||
|
||||
"""
|
||||
|
||||
Pool.__init__(self, creator, **kw)
|
||||
self._pool = self._queue_class(pool_size, use_lifo=use_lifo)
|
||||
self._overflow = 0 - pool_size
|
||||
@@ -249,20 +257,31 @@ class QueuePool(Pool):
|
||||
|
||||
|
||||
class AsyncAdaptedQueuePool(QueuePool):
|
||||
_is_asyncio = True # type: ignore[assignment]
|
||||
_queue_class: Type[
|
||||
sqla_queue.QueueCommon[ConnectionPoolEntry]
|
||||
] = sqla_queue.AsyncAdaptedQueue
|
||||
"""An asyncio-compatible version of :class:`.QueuePool`.
|
||||
|
||||
This pool is used by default when using :class:`.AsyncEngine` engines that
|
||||
were generated from :func:`_asyncio.create_async_engine`. It uses an
|
||||
asyncio-compatible queue implementation that does not use
|
||||
``threading.Lock``.
|
||||
|
||||
The arguments and operation of :class:`.AsyncAdaptedQueuePool` are
|
||||
otherwise identical to that of :class:`.QueuePool`.
|
||||
|
||||
"""
|
||||
|
||||
_is_asyncio = True
|
||||
_queue_class: Type[sqla_queue.QueueCommon[ConnectionPoolEntry]] = (
|
||||
sqla_queue.AsyncAdaptedQueue
|
||||
)
|
||||
|
||||
_dialect = _AsyncConnDialect()
|
||||
|
||||
|
||||
class FallbackAsyncAdaptedQueuePool(AsyncAdaptedQueuePool):
|
||||
_queue_class = sqla_queue.FallbackAsyncAdaptedQueue
|
||||
_queue_class = sqla_queue.FallbackAsyncAdaptedQueue # type: ignore[assignment] # noqa: E501
|
||||
|
||||
|
||||
class NullPool(Pool):
|
||||
|
||||
"""A Pool which does not pool connections.
|
||||
|
||||
Instead it literally opens and closes the underlying DB-API connection
|
||||
@@ -272,6 +291,9 @@ class NullPool(Pool):
|
||||
invalidation are not supported by this Pool implementation, since
|
||||
no connections are held persistently.
|
||||
|
||||
The :class:`.NullPool` class **is compatible** with asyncio and
|
||||
:func:`_asyncio.create_async_engine`.
|
||||
|
||||
"""
|
||||
|
||||
def status(self) -> str:
|
||||
@@ -302,7 +324,6 @@ class NullPool(Pool):
|
||||
|
||||
|
||||
class SingletonThreadPool(Pool):
|
||||
|
||||
"""A Pool that maintains one connection per thread.
|
||||
|
||||
Maintains one connection per each thread, never moving a connection to a
|
||||
@@ -320,6 +341,9 @@ class SingletonThreadPool(Pool):
|
||||
scenarios using a SQLite ``:memory:`` database and is not recommended
|
||||
for production use.
|
||||
|
||||
The :class:`.SingletonThreadPool` class **is not compatible** with asyncio
|
||||
and :func:`_asyncio.create_async_engine`.
|
||||
|
||||
|
||||
Options are the same as those of :class:`_pool.Pool`, as well as:
|
||||
|
||||
@@ -332,7 +356,7 @@ class SingletonThreadPool(Pool):
|
||||
|
||||
"""
|
||||
|
||||
_is_asyncio = False # type: ignore[assignment]
|
||||
_is_asyncio = False
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@@ -422,13 +446,14 @@ class SingletonThreadPool(Pool):
|
||||
|
||||
|
||||
class StaticPool(Pool):
|
||||
|
||||
"""A Pool of exactly one connection, used for all requests.
|
||||
|
||||
Reconnect-related functions such as ``recycle`` and connection
|
||||
invalidation (which is also used to support auto-reconnect) are only
|
||||
partially supported right now and may not yield good results.
|
||||
|
||||
The :class:`.StaticPool` class **is compatible** with asyncio and
|
||||
:func:`_asyncio.create_async_engine`.
|
||||
|
||||
"""
|
||||
|
||||
@@ -486,7 +511,6 @@ class StaticPool(Pool):
|
||||
|
||||
|
||||
class AssertionPool(Pool):
|
||||
|
||||
"""A :class:`_pool.Pool` that allows at most one checked out connection at
|
||||
any given time.
|
||||
|
||||
@@ -494,6 +518,9 @@ class AssertionPool(Pool):
|
||||
at a time. Useful for debugging code that is using more connections
|
||||
than desired.
|
||||
|
||||
The :class:`.AssertionPool` class **is compatible** with asyncio and
|
||||
:func:`_asyncio.create_async_engine`.
|
||||
|
||||
"""
|
||||
|
||||
_conn: Optional[ConnectionPoolEntry]
|
||||
|
||||
Reference in New Issue
Block a user