summaryrefslogtreecommitdiff
path: root/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio
diff options
context:
space:
mode:
authorcyfraeviolae <cyfraeviolae>2024-04-03 03:17:55 -0400
committercyfraeviolae <cyfraeviolae>2024-04-03 03:17:55 -0400
commit12cf076118570eebbff08c6b3090e0d4798447a1 (patch)
tree3ba25e17e3c3a5e82316558ba3864b955919ff72 /venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio
parentc45662ff3923b34614ddcc8feb9195541166dcc5 (diff)
no venv
Diffstat (limited to 'venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio')
-rw-r--r--venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/__init__.py25
-rw-r--r--venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/__pycache__/__init__.cpython-311.pycbin1250 -> 0 bytes
-rw-r--r--venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/__pycache__/base.cpython-311.pycbin12227 -> 0 bytes
-rw-r--r--venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/__pycache__/engine.cpython-311.pycbin59576 -> 0 bytes
-rw-r--r--venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/__pycache__/exc.cpython-311.pycbin1191 -> 0 bytes
-rw-r--r--venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/__pycache__/result.cpython-311.pycbin39306 -> 0 bytes
-rw-r--r--venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/__pycache__/scoping.cpython-311.pycbin57031 -> 0 bytes
-rw-r--r--venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/__pycache__/session.cpython-311.pycbin72886 -> 0 bytes
-rw-r--r--venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/base.py279
-rw-r--r--venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/engine.py1466
-rw-r--r--venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/exc.py21
-rw-r--r--venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/result.py961
-rw-r--r--venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/scoping.py1614
-rw-r--r--venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/session.py1936
14 files changed, 0 insertions, 6302 deletions
diff --git a/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/__init__.py b/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/__init__.py
deleted file mode 100644
index 78c707b..0000000
--- a/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/__init__.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# ext/asyncio/__init__.py
-# Copyright (C) 2020-2024 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
-
-from .engine import async_engine_from_config as async_engine_from_config
-from .engine import AsyncConnection as AsyncConnection
-from .engine import AsyncEngine as AsyncEngine
-from .engine import AsyncTransaction as AsyncTransaction
-from .engine import create_async_engine as create_async_engine
-from .engine import create_async_pool_from_url as create_async_pool_from_url
-from .result import AsyncMappingResult as AsyncMappingResult
-from .result import AsyncResult as AsyncResult
-from .result import AsyncScalarResult as AsyncScalarResult
-from .result import AsyncTupleResult as AsyncTupleResult
-from .scoping import async_scoped_session as async_scoped_session
-from .session import async_object_session as async_object_session
-from .session import async_session as async_session
-from .session import async_sessionmaker as async_sessionmaker
-from .session import AsyncAttrs as AsyncAttrs
-from .session import AsyncSession as AsyncSession
-from .session import AsyncSessionTransaction as AsyncSessionTransaction
-from .session import close_all_sessions as close_all_sessions
diff --git a/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/__pycache__/__init__.cpython-311.pyc
deleted file mode 100644
index a647d42..0000000
--- a/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/__pycache__/__init__.cpython-311.pyc
+++ /dev/null
Binary files differ
diff --git a/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/__pycache__/base.cpython-311.pyc b/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/__pycache__/base.cpython-311.pyc
deleted file mode 100644
index 785ef03..0000000
--- a/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/__pycache__/base.cpython-311.pyc
+++ /dev/null
Binary files differ
diff --git a/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/__pycache__/engine.cpython-311.pyc b/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/__pycache__/engine.cpython-311.pyc
deleted file mode 100644
index 4326d1c..0000000
--- a/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/__pycache__/engine.cpython-311.pyc
+++ /dev/null
Binary files differ
diff --git a/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/__pycache__/exc.cpython-311.pyc b/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/__pycache__/exc.cpython-311.pyc
deleted file mode 100644
index 5a71fac..0000000
--- a/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/__pycache__/exc.cpython-311.pyc
+++ /dev/null
Binary files differ
diff --git a/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/__pycache__/result.cpython-311.pyc b/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/__pycache__/result.cpython-311.pyc
deleted file mode 100644
index c6ae583..0000000
--- a/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/__pycache__/result.cpython-311.pyc
+++ /dev/null
Binary files differ
diff --git a/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/__pycache__/scoping.cpython-311.pyc b/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/__pycache__/scoping.cpython-311.pyc
deleted file mode 100644
index 8839d42..0000000
--- a/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/__pycache__/scoping.cpython-311.pyc
+++ /dev/null
Binary files differ
diff --git a/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/__pycache__/session.cpython-311.pyc b/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/__pycache__/session.cpython-311.pyc
deleted file mode 100644
index 0c267a0..0000000
--- a/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/__pycache__/session.cpython-311.pyc
+++ /dev/null
Binary files differ
diff --git a/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/base.py b/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/base.py
deleted file mode 100644
index 9899364..0000000
--- a/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/base.py
+++ /dev/null
@@ -1,279 +0,0 @@
-# ext/asyncio/base.py
-# Copyright (C) 2020-2024 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
-
-from __future__ import annotations
-
-import abc
-import functools
-from typing import Any
-from typing import AsyncGenerator
-from typing import AsyncIterator
-from typing import Awaitable
-from typing import Callable
-from typing import ClassVar
-from typing import Dict
-from typing import Generator
-from typing import Generic
-from typing import NoReturn
-from typing import Optional
-from typing import overload
-from typing import Tuple
-from typing import TypeVar
-import weakref
-
-from . import exc as async_exc
-from ... import util
-from ...util.typing import Literal
-from ...util.typing import Self
-
-_T = TypeVar("_T", bound=Any)
-_T_co = TypeVar("_T_co", bound=Any, covariant=True)
-
-
-_PT = TypeVar("_PT", bound=Any)
-
-
-class ReversibleProxy(Generic[_PT]):
- _proxy_objects: ClassVar[
- Dict[weakref.ref[Any], weakref.ref[ReversibleProxy[Any]]]
- ] = {}
- __slots__ = ("__weakref__",)
-
- @overload
- def _assign_proxied(self, target: _PT) -> _PT: ...
-
- @overload
- def _assign_proxied(self, target: None) -> None: ...
-
- def _assign_proxied(self, target: Optional[_PT]) -> Optional[_PT]:
- if target is not None:
- target_ref: weakref.ref[_PT] = weakref.ref(
- target, ReversibleProxy._target_gced
- )
- proxy_ref = weakref.ref(
- self,
- functools.partial(ReversibleProxy._target_gced, target_ref),
- )
- ReversibleProxy._proxy_objects[target_ref] = proxy_ref
-
- return target
-
- @classmethod
- def _target_gced(
- cls,
- ref: weakref.ref[_PT],
- proxy_ref: Optional[weakref.ref[Self]] = None, # noqa: U100
- ) -> None:
- cls._proxy_objects.pop(ref, None)
-
- @classmethod
- def _regenerate_proxy_for_target(cls, target: _PT) -> Self:
- raise NotImplementedError()
-
- @overload
- @classmethod
- def _retrieve_proxy_for_target(
- cls,
- target: _PT,
- regenerate: Literal[True] = ...,
- ) -> Self: ...
-
- @overload
- @classmethod
- def _retrieve_proxy_for_target(
- cls, target: _PT, regenerate: bool = True
- ) -> Optional[Self]: ...
-
- @classmethod
- def _retrieve_proxy_for_target(
- cls, target: _PT, regenerate: bool = True
- ) -> Optional[Self]:
- try:
- proxy_ref = cls._proxy_objects[weakref.ref(target)]
- except KeyError:
- pass
- else:
- proxy = proxy_ref()
- if proxy is not None:
- return proxy # type: ignore
-
- if regenerate:
- return cls._regenerate_proxy_for_target(target)
- else:
- return None
-
-
-class StartableContext(Awaitable[_T_co], abc.ABC):
- __slots__ = ()
-
- @abc.abstractmethod
- async def start(self, is_ctxmanager: bool = False) -> _T_co:
- raise NotImplementedError()
-
- def __await__(self) -> Generator[Any, Any, _T_co]:
- return self.start().__await__()
-
- async def __aenter__(self) -> _T_co:
- return await self.start(is_ctxmanager=True)
-
- @abc.abstractmethod
- async def __aexit__(
- self, type_: Any, value: Any, traceback: Any
- ) -> Optional[bool]:
- pass
-
- def _raise_for_not_started(self) -> NoReturn:
- raise async_exc.AsyncContextNotStarted(
- "%s context has not been started and object has not been awaited."
- % (self.__class__.__name__)
- )
-
-
-class GeneratorStartableContext(StartableContext[_T_co]):
- __slots__ = ("gen",)
-
- gen: AsyncGenerator[_T_co, Any]
-
- def __init__(
- self,
- func: Callable[..., AsyncIterator[_T_co]],
- args: Tuple[Any, ...],
- kwds: Dict[str, Any],
- ):
- self.gen = func(*args, **kwds) # type: ignore
-
- async def start(self, is_ctxmanager: bool = False) -> _T_co:
- try:
- start_value = await util.anext_(self.gen)
- except StopAsyncIteration:
- raise RuntimeError("generator didn't yield") from None
-
- # if not a context manager, then interrupt the generator, don't
- # let it complete. this step is technically not needed, as the
- # generator will close in any case at gc time. not clear if having
- # this here is a good idea or not (though it helps for clarity IMO)
- if not is_ctxmanager:
- await self.gen.aclose()
-
- return start_value
-
- async def __aexit__(
- self, typ: Any, value: Any, traceback: Any
- ) -> Optional[bool]:
- # vendored from contextlib.py
- if typ is None:
- try:
- await util.anext_(self.gen)
- except StopAsyncIteration:
- return False
- else:
- raise RuntimeError("generator didn't stop")
- else:
- if value is None:
- # Need to force instantiation so we can reliably
- # tell if we get the same exception back
- value = typ()
- try:
- await self.gen.athrow(value)
- except StopAsyncIteration as exc:
- # Suppress StopIteration *unless* it's the same exception that
- # was passed to throw(). This prevents a StopIteration
- # raised inside the "with" statement from being suppressed.
- return exc is not value
- except RuntimeError as exc:
- # Don't re-raise the passed in exception. (issue27122)
- if exc is value:
- return False
- # Avoid suppressing if a Stop(Async)Iteration exception
- # was passed to athrow() and later wrapped into a RuntimeError
- # (see PEP 479 for sync generators; async generators also
- # have this behavior). But do this only if the exception
- # wrapped
- # by the RuntimeError is actully Stop(Async)Iteration (see
- # issue29692).
- if (
- isinstance(value, (StopIteration, StopAsyncIteration))
- and exc.__cause__ is value
- ):
- return False
- raise
- except BaseException as exc:
- # only re-raise if it's *not* the exception that was
- # passed to throw(), because __exit__() must not raise
- # an exception unless __exit__() itself failed. But throw()
- # has to raise the exception to signal propagation, so this
- # fixes the impedance mismatch between the throw() protocol
- # and the __exit__() protocol.
- if exc is not value:
- raise
- return False
- raise RuntimeError("generator didn't stop after athrow()")
-
-
-def asyncstartablecontext(
- func: Callable[..., AsyncIterator[_T_co]]
-) -> Callable[..., GeneratorStartableContext[_T_co]]:
- """@asyncstartablecontext decorator.
-
- the decorated function can be called either as ``async with fn()``, **or**
- ``await fn()``. This is decidedly different from what
- ``@contextlib.asynccontextmanager`` supports, and the usage pattern
- is different as well.
-
- Typical usage::
-
- @asyncstartablecontext
- async def some_async_generator(<arguments>):
- <setup>
- try:
- yield <value>
- except GeneratorExit:
- # return value was awaited, no context manager is present
- # and caller will .close() the resource explicitly
- pass
- else:
- <context manager cleanup>
-
-
- Above, ``GeneratorExit`` is caught if the function were used as an
- ``await``. In this case, it's essential that the cleanup does **not**
- occur, so there should not be a ``finally`` block.
-
- If ``GeneratorExit`` is not invoked, this means we're in ``__aexit__``
- and we were invoked as a context manager, and cleanup should proceed.
-
-
- """
-
- @functools.wraps(func)
- def helper(*args: Any, **kwds: Any) -> GeneratorStartableContext[_T_co]:
- return GeneratorStartableContext(func, args, kwds)
-
- return helper
-
-
-class ProxyComparable(ReversibleProxy[_PT]):
- __slots__ = ()
-
- @util.ro_non_memoized_property
- def _proxied(self) -> _PT:
- raise NotImplementedError()
-
- def __hash__(self) -> int:
- return id(self)
-
- def __eq__(self, other: Any) -> bool:
- return (
- isinstance(other, self.__class__)
- and self._proxied == other._proxied
- )
-
- def __ne__(self, other: Any) -> bool:
- return (
- not isinstance(other, self.__class__)
- or self._proxied != other._proxied
- )
diff --git a/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/engine.py b/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/engine.py
deleted file mode 100644
index 8fc8e96..0000000
--- a/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/engine.py
+++ /dev/null
@@ -1,1466 +0,0 @@
-# ext/asyncio/engine.py
-# Copyright (C) 2020-2024 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
-from __future__ import annotations
-
-import asyncio
-import contextlib
-from typing import Any
-from typing import AsyncIterator
-from typing import Callable
-from typing import Dict
-from typing import Generator
-from typing import NoReturn
-from typing import Optional
-from typing import overload
-from typing import Tuple
-from typing import Type
-from typing import TYPE_CHECKING
-from typing import TypeVar
-from typing import Union
-
-from . import exc as async_exc
-from .base import asyncstartablecontext
-from .base import GeneratorStartableContext
-from .base import ProxyComparable
-from .base import StartableContext
-from .result import _ensure_sync_result
-from .result import AsyncResult
-from .result import AsyncScalarResult
-from ... import exc
-from ... import inspection
-from ... import util
-from ...engine import Connection
-from ...engine import create_engine as _create_engine
-from ...engine import create_pool_from_url as _create_pool_from_url
-from ...engine import Engine
-from ...engine.base import NestedTransaction
-from ...engine.base import Transaction
-from ...exc import ArgumentError
-from ...util.concurrency import greenlet_spawn
-from ...util.typing import Concatenate
-from ...util.typing import ParamSpec
-
-if TYPE_CHECKING:
- from ...engine.cursor import CursorResult
- from ...engine.interfaces import _CoreAnyExecuteParams
- from ...engine.interfaces import _CoreSingleExecuteParams
- from ...engine.interfaces import _DBAPIAnyExecuteParams
- from ...engine.interfaces import _ExecuteOptions
- from ...engine.interfaces import CompiledCacheType
- from ...engine.interfaces import CoreExecuteOptionsParameter
- from ...engine.interfaces import Dialect
- from ...engine.interfaces import IsolationLevel
- from ...engine.interfaces import SchemaTranslateMapType
- from ...engine.result import ScalarResult
- from ...engine.url import URL
- from ...pool import Pool
- from ...pool import PoolProxiedConnection
- from ...sql._typing import _InfoType
- from ...sql.base import Executable
- from ...sql.selectable import TypedReturnsRows
-
-_P = ParamSpec("_P")
-_T = TypeVar("_T", bound=Any)
-
-
-def create_async_engine(url: Union[str, URL], **kw: Any) -> AsyncEngine:
- """Create a new async engine instance.
-
- Arguments passed to :func:`_asyncio.create_async_engine` are mostly
- identical to those passed to the :func:`_sa.create_engine` function.
- The specified dialect must be an asyncio-compatible dialect
- such as :ref:`dialect-postgresql-asyncpg`.
-
- .. versionadded:: 1.4
-
- :param async_creator: an async callable which returns a driver-level
- asyncio connection. If given, the function should take no arguments,
- and return a new asyncio connection from the underlying asyncio
- database driver; the connection will be wrapped in the appropriate
- structures to be used with the :class:`.AsyncEngine`. Note that the
- parameters specified in the URL are not applied here, and the creator
- function should use its own connection parameters.
-
- This parameter is the asyncio equivalent of the
- :paramref:`_sa.create_engine.creator` parameter of the
- :func:`_sa.create_engine` function.
-
- .. versionadded:: 2.0.16
-
- """
-
- if kw.get("server_side_cursors", False):
- raise async_exc.AsyncMethodRequired(
- "Can't set server_side_cursors for async engine globally; "
- "use the connection.stream() method for an async "
- "streaming result set"
- )
- kw["_is_async"] = True
- async_creator = kw.pop("async_creator", None)
- if async_creator:
- if kw.get("creator", None):
- raise ArgumentError(
- "Can only specify one of 'async_creator' or 'creator', "
- "not both."
- )
-
- def creator() -> Any:
- # note that to send adapted arguments like
- # prepared_statement_cache_size, user would use
- # "creator" and emulate this form here
- return sync_engine.dialect.dbapi.connect( # type: ignore
- async_creator_fn=async_creator
- )
-
- kw["creator"] = creator
- sync_engine = _create_engine(url, **kw)
- return AsyncEngine(sync_engine)
-
-
-def async_engine_from_config(
- configuration: Dict[str, Any], prefix: str = "sqlalchemy.", **kwargs: Any
-) -> AsyncEngine:
- """Create a new AsyncEngine instance using a configuration dictionary.
-
- This function is analogous to the :func:`_sa.engine_from_config` function
- in SQLAlchemy Core, except that the requested dialect must be an
- asyncio-compatible dialect such as :ref:`dialect-postgresql-asyncpg`.
- The argument signature of the function is identical to that
- of :func:`_sa.engine_from_config`.
-
- .. versionadded:: 1.4.29
-
- """
- options = {
- key[len(prefix) :]: value
- for key, value in configuration.items()
- if key.startswith(prefix)
- }
- options["_coerce_config"] = True
- options.update(kwargs)
- url = options.pop("url")
- return create_async_engine(url, **options)
-
-
-def create_async_pool_from_url(url: Union[str, URL], **kwargs: Any) -> Pool:
- """Create a new async engine instance.
-
- Arguments passed to :func:`_asyncio.create_async_pool_from_url` are mostly
- identical to those passed to the :func:`_sa.create_pool_from_url` function.
- The specified dialect must be an asyncio-compatible dialect
- such as :ref:`dialect-postgresql-asyncpg`.
-
- .. versionadded:: 2.0.10
-
- """
- kwargs["_is_async"] = True
- return _create_pool_from_url(url, **kwargs)
-
-
-class AsyncConnectable:
- __slots__ = "_slots_dispatch", "__weakref__"
-
- @classmethod
- def _no_async_engine_events(cls) -> NoReturn:
- raise NotImplementedError(
- "asynchronous events are not implemented at this time. Apply "
- "synchronous listeners to the AsyncEngine.sync_engine or "
- "AsyncConnection.sync_connection attributes."
- )
-
-
-@util.create_proxy_methods(
- Connection,
- ":class:`_engine.Connection`",
- ":class:`_asyncio.AsyncConnection`",
- classmethods=[],
- methods=[],
- attributes=[
- "closed",
- "invalidated",
- "dialect",
- "default_isolation_level",
- ],
-)
-class AsyncConnection(
- ProxyComparable[Connection],
- StartableContext["AsyncConnection"],
- AsyncConnectable,
-):
- """An asyncio proxy for a :class:`_engine.Connection`.
-
- :class:`_asyncio.AsyncConnection` is acquired using the
- :meth:`_asyncio.AsyncEngine.connect`
- method of :class:`_asyncio.AsyncEngine`::
-
- from sqlalchemy.ext.asyncio import create_async_engine
- engine = create_async_engine("postgresql+asyncpg://user:pass@host/dbname")
-
- async with engine.connect() as conn:
- result = await conn.execute(select(table))
-
- .. versionadded:: 1.4
-
- """ # noqa
-
- # AsyncConnection is a thin proxy; no state should be added here
- # that is not retrievable from the "sync" engine / connection, e.g.
- # current transaction, info, etc. It should be possible to
- # create a new AsyncConnection that matches this one given only the
- # "sync" elements.
- __slots__ = (
- "engine",
- "sync_engine",
- "sync_connection",
- )
-
- def __init__(
- self,
- async_engine: AsyncEngine,
- sync_connection: Optional[Connection] = None,
- ):
- self.engine = async_engine
- self.sync_engine = async_engine.sync_engine
- self.sync_connection = self._assign_proxied(sync_connection)
-
- sync_connection: Optional[Connection]
- """Reference to the sync-style :class:`_engine.Connection` this
- :class:`_asyncio.AsyncConnection` proxies requests towards.
-
- This instance can be used as an event target.
-
- .. seealso::
-
- :ref:`asyncio_events`
-
- """
-
- sync_engine: Engine
- """Reference to the sync-style :class:`_engine.Engine` this
- :class:`_asyncio.AsyncConnection` is associated with via its underlying
- :class:`_engine.Connection`.
-
- This instance can be used as an event target.
-
- .. seealso::
-
- :ref:`asyncio_events`
-
- """
-
- @classmethod
- def _regenerate_proxy_for_target(
- cls, target: Connection
- ) -> AsyncConnection:
- return AsyncConnection(
- AsyncEngine._retrieve_proxy_for_target(target.engine), target
- )
-
- async def start(
- self, is_ctxmanager: bool = False # noqa: U100
- ) -> AsyncConnection:
- """Start this :class:`_asyncio.AsyncConnection` object's context
- outside of using a Python ``with:`` block.
-
- """
- if self.sync_connection:
- raise exc.InvalidRequestError("connection is already started")
- self.sync_connection = self._assign_proxied(
- await greenlet_spawn(self.sync_engine.connect)
- )
- return self
-
- @property
- def connection(self) -> NoReturn:
- """Not implemented for async; call
- :meth:`_asyncio.AsyncConnection.get_raw_connection`.
- """
- raise exc.InvalidRequestError(
- "AsyncConnection.connection accessor is not implemented as the "
- "attribute may need to reconnect on an invalidated connection. "
- "Use the get_raw_connection() method."
- )
-
- async def get_raw_connection(self) -> PoolProxiedConnection:
- """Return the pooled DBAPI-level connection in use by this
- :class:`_asyncio.AsyncConnection`.
-
- This is a SQLAlchemy connection-pool proxied connection
- which then has the attribute
- :attr:`_pool._ConnectionFairy.driver_connection` that refers to the
- actual driver connection. Its
- :attr:`_pool._ConnectionFairy.dbapi_connection` refers instead
- to an :class:`_engine.AdaptedConnection` instance that
- adapts the driver connection to the DBAPI protocol.
-
- """
-
- return await greenlet_spawn(getattr, self._proxied, "connection")
-
- @util.ro_non_memoized_property
- def info(self) -> _InfoType:
- """Return the :attr:`_engine.Connection.info` dictionary of the
- underlying :class:`_engine.Connection`.
-
- This dictionary is freely writable for user-defined state to be
- associated with the database connection.
-
- This attribute is only available if the :class:`.AsyncConnection` is
- currently connected. If the :attr:`.AsyncConnection.closed` attribute
- is ``True``, then accessing this attribute will raise
- :class:`.ResourceClosedError`.
-
- .. versionadded:: 1.4.0b2
-
- """
- return self._proxied.info
-
- @util.ro_non_memoized_property
- def _proxied(self) -> Connection:
- if not self.sync_connection:
- self._raise_for_not_started()
- return self.sync_connection
-
- def begin(self) -> AsyncTransaction:
- """Begin a transaction prior to autobegin occurring."""
- assert self._proxied
- return AsyncTransaction(self)
-
- def begin_nested(self) -> AsyncTransaction:
- """Begin a nested transaction and return a transaction handle."""
- assert self._proxied
- return AsyncTransaction(self, nested=True)
-
- async def invalidate(
- self, exception: Optional[BaseException] = None
- ) -> None:
- """Invalidate the underlying DBAPI connection associated with
- this :class:`_engine.Connection`.
-
- See the method :meth:`_engine.Connection.invalidate` for full
- detail on this method.
-
- """
-
- return await greenlet_spawn(
- self._proxied.invalidate, exception=exception
- )
-
- async def get_isolation_level(self) -> IsolationLevel:
- return await greenlet_spawn(self._proxied.get_isolation_level)
-
- def in_transaction(self) -> bool:
- """Return True if a transaction is in progress."""
-
- return self._proxied.in_transaction()
-
- def in_nested_transaction(self) -> bool:
- """Return True if a transaction is in progress.
-
- .. versionadded:: 1.4.0b2
-
- """
- return self._proxied.in_nested_transaction()
-
- def get_transaction(self) -> Optional[AsyncTransaction]:
- """Return an :class:`.AsyncTransaction` representing the current
- transaction, if any.
-
- This makes use of the underlying synchronous connection's
- :meth:`_engine.Connection.get_transaction` method to get the current
- :class:`_engine.Transaction`, which is then proxied in a new
- :class:`.AsyncTransaction` object.
-
- .. versionadded:: 1.4.0b2
-
- """
-
- trans = self._proxied.get_transaction()
- if trans is not None:
- return AsyncTransaction._retrieve_proxy_for_target(trans)
- else:
- return None
-
- def get_nested_transaction(self) -> Optional[AsyncTransaction]:
- """Return an :class:`.AsyncTransaction` representing the current
- nested (savepoint) transaction, if any.
-
- This makes use of the underlying synchronous connection's
- :meth:`_engine.Connection.get_nested_transaction` method to get the
- current :class:`_engine.Transaction`, which is then proxied in a new
- :class:`.AsyncTransaction` object.
-
- .. versionadded:: 1.4.0b2
-
- """
-
- trans = self._proxied.get_nested_transaction()
- if trans is not None:
- return AsyncTransaction._retrieve_proxy_for_target(trans)
- else:
- return None
-
- @overload
- async def execution_options(
- self,
- *,
- compiled_cache: Optional[CompiledCacheType] = ...,
- logging_token: str = ...,
- isolation_level: IsolationLevel = ...,
- no_parameters: bool = False,
- stream_results: bool = False,
- max_row_buffer: int = ...,
- yield_per: int = ...,
- insertmanyvalues_page_size: int = ...,
- schema_translate_map: Optional[SchemaTranslateMapType] = ...,
- preserve_rowcount: bool = False,
- **opt: Any,
- ) -> AsyncConnection: ...
-
- @overload
- async def execution_options(self, **opt: Any) -> AsyncConnection: ...
-
- async def execution_options(self, **opt: Any) -> AsyncConnection:
- r"""Set non-SQL options for the connection which take effect
- during execution.
-
- This returns this :class:`_asyncio.AsyncConnection` object with
- the new options added.
-
- See :meth:`_engine.Connection.execution_options` for full details
- on this method.
-
- """
-
- conn = self._proxied
- c2 = await greenlet_spawn(conn.execution_options, **opt)
- assert c2 is conn
- return self
-
- async def commit(self) -> None:
- """Commit the transaction that is currently in progress.
-
- This method commits the current transaction if one has been started.
- If no transaction was started, the method has no effect, assuming
- the connection is in a non-invalidated state.
-
- A transaction is begun on a :class:`_engine.Connection` automatically
- whenever a statement is first executed, or when the
- :meth:`_engine.Connection.begin` method is called.
-
- """
- await greenlet_spawn(self._proxied.commit)
-
- async def rollback(self) -> None:
- """Roll back the transaction that is currently in progress.
-
- This method rolls back the current transaction if one has been started.
- If no transaction was started, the method has no effect. If a
- transaction was started and the connection is in an invalidated state,
- the transaction is cleared using this method.
-
- A transaction is begun on a :class:`_engine.Connection` automatically
- whenever a statement is first executed, or when the
- :meth:`_engine.Connection.begin` method is called.
-
-
- """
- await greenlet_spawn(self._proxied.rollback)
-
- async def close(self) -> None:
- """Close this :class:`_asyncio.AsyncConnection`.
-
- This has the effect of also rolling back the transaction if one
- is in place.
-
- """
- await greenlet_spawn(self._proxied.close)
-
- async def aclose(self) -> None:
- """A synonym for :meth:`_asyncio.AsyncConnection.close`.
-
- The :meth:`_asyncio.AsyncConnection.aclose` name is specifically
- to support the Python standard library ``@contextlib.aclosing``
- context manager function.
-
- .. versionadded:: 2.0.20
-
- """
- await self.close()
-
- async def exec_driver_sql(
- self,
- statement: str,
- parameters: Optional[_DBAPIAnyExecuteParams] = None,
- execution_options: Optional[CoreExecuteOptionsParameter] = None,
- ) -> CursorResult[Any]:
- r"""Executes a driver-level SQL string and return buffered
- :class:`_engine.Result`.
-
- """
-
- result = await greenlet_spawn(
- self._proxied.exec_driver_sql,
- statement,
- parameters,
- execution_options,
- _require_await=True,
- )
-
- return await _ensure_sync_result(result, self.exec_driver_sql)
-
- @overload
- def stream(
- self,
- statement: TypedReturnsRows[_T],
- parameters: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: Optional[CoreExecuteOptionsParameter] = None,
- ) -> GeneratorStartableContext[AsyncResult[_T]]: ...
-
- @overload
- def stream(
- self,
- statement: Executable,
- parameters: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: Optional[CoreExecuteOptionsParameter] = None,
- ) -> GeneratorStartableContext[AsyncResult[Any]]: ...
-
- @asyncstartablecontext
- async def stream(
- self,
- statement: Executable,
- parameters: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: Optional[CoreExecuteOptionsParameter] = None,
- ) -> AsyncIterator[AsyncResult[Any]]:
- """Execute a statement and return an awaitable yielding a
- :class:`_asyncio.AsyncResult` object.
-
- E.g.::
-
- result = await conn.stream(stmt):
- async for row in result:
- print(f"{row}")
-
- The :meth:`.AsyncConnection.stream`
- method supports optional context manager use against the
- :class:`.AsyncResult` object, as in::
-
- async with conn.stream(stmt) as result:
- async for row in result:
- print(f"{row}")
-
- In the above pattern, the :meth:`.AsyncResult.close` method is
- invoked unconditionally, even if the iterator is interrupted by an
- exception throw. Context manager use remains optional, however,
- and the function may be called in either an ``async with fn():`` or
- ``await fn()`` style.
-
- .. versionadded:: 2.0.0b3 added context manager support
-
-
- :return: an awaitable object that will yield an
- :class:`_asyncio.AsyncResult` object.
-
- .. seealso::
-
- :meth:`.AsyncConnection.stream_scalars`
-
- """
- if not self.dialect.supports_server_side_cursors:
- raise exc.InvalidRequestError(
- "Cant use `stream` or `stream_scalars` with the current "
- "dialect since it does not support server side cursors."
- )
-
- result = await greenlet_spawn(
- self._proxied.execute,
- statement,
- parameters,
- execution_options=util.EMPTY_DICT.merge_with(
- execution_options, {"stream_results": True}
- ),
- _require_await=True,
- )
- assert result.context._is_server_side
- ar = AsyncResult(result)
- try:
- yield ar
- except GeneratorExit:
- pass
- else:
- task = asyncio.create_task(ar.close())
- await asyncio.shield(task)
-
- @overload
- async def execute(
- self,
- statement: TypedReturnsRows[_T],
- parameters: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: Optional[CoreExecuteOptionsParameter] = None,
- ) -> CursorResult[_T]: ...
-
- @overload
- async def execute(
- self,
- statement: Executable,
- parameters: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: Optional[CoreExecuteOptionsParameter] = None,
- ) -> CursorResult[Any]: ...
-
- async def execute(
- self,
- statement: Executable,
- parameters: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: Optional[CoreExecuteOptionsParameter] = None,
- ) -> CursorResult[Any]:
- r"""Executes a SQL statement construct and return a buffered
- :class:`_engine.Result`.
-
- :param object: The statement to be executed. This is always
- an object that is in both the :class:`_expression.ClauseElement` and
- :class:`_expression.Executable` hierarchies, including:
-
- * :class:`_expression.Select`
- * :class:`_expression.Insert`, :class:`_expression.Update`,
- :class:`_expression.Delete`
- * :class:`_expression.TextClause` and
- :class:`_expression.TextualSelect`
- * :class:`_schema.DDL` and objects which inherit from
- :class:`_schema.ExecutableDDLElement`
-
- :param parameters: parameters which will be bound into the statement.
- This may be either a dictionary of parameter names to values,
- or a mutable sequence (e.g. a list) of dictionaries. When a
- list of dictionaries is passed, the underlying statement execution
- will make use of the DBAPI ``cursor.executemany()`` method.
- When a single dictionary is passed, the DBAPI ``cursor.execute()``
- method will be used.
-
- :param execution_options: optional dictionary of execution options,
- which will be associated with the statement execution. This
- dictionary can provide a subset of the options that are accepted
- by :meth:`_engine.Connection.execution_options`.
-
- :return: a :class:`_engine.Result` object.
-
- """
- result = await greenlet_spawn(
- self._proxied.execute,
- statement,
- parameters,
- execution_options=execution_options,
- _require_await=True,
- )
- return await _ensure_sync_result(result, self.execute)
-
- @overload
- async def scalar(
- self,
- statement: TypedReturnsRows[Tuple[_T]],
- parameters: Optional[_CoreSingleExecuteParams] = None,
- *,
- execution_options: Optional[CoreExecuteOptionsParameter] = None,
- ) -> Optional[_T]: ...
-
- @overload
- async def scalar(
- self,
- statement: Executable,
- parameters: Optional[_CoreSingleExecuteParams] = None,
- *,
- execution_options: Optional[CoreExecuteOptionsParameter] = None,
- ) -> Any: ...
-
- async def scalar(
- self,
- statement: Executable,
- parameters: Optional[_CoreSingleExecuteParams] = None,
- *,
- execution_options: Optional[CoreExecuteOptionsParameter] = None,
- ) -> Any:
- r"""Executes a SQL statement construct and returns a scalar object.
-
- This method is shorthand for invoking the
- :meth:`_engine.Result.scalar` method after invoking the
- :meth:`_engine.Connection.execute` method. Parameters are equivalent.
-
- :return: a scalar Python value representing the first column of the
- first row returned.
-
- """
- result = await self.execute(
- statement, parameters, execution_options=execution_options
- )
- return result.scalar()
-
- @overload
- async def scalars(
- self,
- statement: TypedReturnsRows[Tuple[_T]],
- parameters: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: Optional[CoreExecuteOptionsParameter] = None,
- ) -> ScalarResult[_T]: ...
-
- @overload
- async def scalars(
- self,
- statement: Executable,
- parameters: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: Optional[CoreExecuteOptionsParameter] = None,
- ) -> ScalarResult[Any]: ...
-
- async def scalars(
- self,
- statement: Executable,
- parameters: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: Optional[CoreExecuteOptionsParameter] = None,
- ) -> ScalarResult[Any]:
- r"""Executes a SQL statement construct and returns a scalar objects.
-
- This method is shorthand for invoking the
- :meth:`_engine.Result.scalars` method after invoking the
- :meth:`_engine.Connection.execute` method. Parameters are equivalent.
-
- :return: a :class:`_engine.ScalarResult` object.
-
- .. versionadded:: 1.4.24
-
- """
- result = await self.execute(
- statement, parameters, execution_options=execution_options
- )
- return result.scalars()
-
- @overload
- def stream_scalars(
- self,
- statement: TypedReturnsRows[Tuple[_T]],
- parameters: Optional[_CoreSingleExecuteParams] = None,
- *,
- execution_options: Optional[CoreExecuteOptionsParameter] = None,
- ) -> GeneratorStartableContext[AsyncScalarResult[_T]]: ...
-
- @overload
- def stream_scalars(
- self,
- statement: Executable,
- parameters: Optional[_CoreSingleExecuteParams] = None,
- *,
- execution_options: Optional[CoreExecuteOptionsParameter] = None,
- ) -> GeneratorStartableContext[AsyncScalarResult[Any]]: ...
-
- @asyncstartablecontext
- async def stream_scalars(
- self,
- statement: Executable,
- parameters: Optional[_CoreSingleExecuteParams] = None,
- *,
- execution_options: Optional[CoreExecuteOptionsParameter] = None,
- ) -> AsyncIterator[AsyncScalarResult[Any]]:
- r"""Execute a statement and return an awaitable yielding a
- :class:`_asyncio.AsyncScalarResult` object.
-
- E.g.::
-
- result = await conn.stream_scalars(stmt)
- async for scalar in result:
- print(f"{scalar}")
-
- This method is shorthand for invoking the
- :meth:`_engine.AsyncResult.scalars` method after invoking the
- :meth:`_engine.Connection.stream` method. Parameters are equivalent.
-
- The :meth:`.AsyncConnection.stream_scalars`
- method supports optional context manager use against the
- :class:`.AsyncScalarResult` object, as in::
-
- async with conn.stream_scalars(stmt) as result:
- async for scalar in result:
- print(f"{scalar}")
-
- In the above pattern, the :meth:`.AsyncScalarResult.close` method is
- invoked unconditionally, even if the iterator is interrupted by an
- exception throw. Context manager use remains optional, however,
- and the function may be called in either an ``async with fn():`` or
- ``await fn()`` style.
-
- .. versionadded:: 2.0.0b3 added context manager support
-
- :return: an awaitable object that will yield an
- :class:`_asyncio.AsyncScalarResult` object.
-
- .. versionadded:: 1.4.24
-
- .. seealso::
-
- :meth:`.AsyncConnection.stream`
-
- """
-
- async with self.stream(
- statement, parameters, execution_options=execution_options
- ) as result:
- yield result.scalars()
-
- async def run_sync(
- self,
- fn: Callable[Concatenate[Connection, _P], _T],
- *arg: _P.args,
- **kw: _P.kwargs,
- ) -> _T:
- """Invoke the given synchronous (i.e. not async) callable,
- passing a synchronous-style :class:`_engine.Connection` as the first
- argument.
-
- This method allows traditional synchronous SQLAlchemy functions to
- run within the context of an asyncio application.
-
- E.g.::
-
- def do_something_with_core(conn: Connection, arg1: int, arg2: str) -> str:
- '''A synchronous function that does not require awaiting
-
- :param conn: a Core SQLAlchemy Connection, used synchronously
-
- :return: an optional return value is supported
-
- '''
- conn.execute(
- some_table.insert().values(int_col=arg1, str_col=arg2)
- )
- return "success"
-
-
- async def do_something_async(async_engine: AsyncEngine) -> None:
- '''an async function that uses awaiting'''
-
- async with async_engine.begin() as async_conn:
- # run do_something_with_core() with a sync-style
- # Connection, proxied into an awaitable
- return_code = await async_conn.run_sync(do_something_with_core, 5, "strval")
- print(return_code)
-
- This method maintains the asyncio event loop all the way through
- to the database connection by running the given callable in a
- specially instrumented greenlet.
-
- The most rudimentary use of :meth:`.AsyncConnection.run_sync` is to
- invoke methods such as :meth:`_schema.MetaData.create_all`, given
- an :class:`.AsyncConnection` that needs to be provided to
- :meth:`_schema.MetaData.create_all` as a :class:`_engine.Connection`
- object::
-
- # run metadata.create_all(conn) with a sync-style Connection,
- # proxied into an awaitable
- with async_engine.begin() as conn:
- await conn.run_sync(metadata.create_all)
-
- .. note::
-
- The provided callable is invoked inline within the asyncio event
- loop, and will block on traditional IO calls. IO within this
- callable should only call into SQLAlchemy's asyncio database
- APIs which will be properly adapted to the greenlet context.
-
- .. seealso::
-
- :meth:`.AsyncSession.run_sync`
-
- :ref:`session_run_sync`
-
- """ # noqa: E501
-
- return await greenlet_spawn(
- fn, self._proxied, *arg, _require_await=False, **kw
- )
-
- def __await__(self) -> Generator[Any, None, AsyncConnection]:
- return self.start().__await__()
-
- async def __aexit__(self, type_: Any, value: Any, traceback: Any) -> None:
- task = asyncio.create_task(self.close())
- await asyncio.shield(task)
-
- # START PROXY METHODS AsyncConnection
-
- # code within this block is **programmatically,
- # statically generated** by tools/generate_proxy_methods.py
-
- @property
- def closed(self) -> Any:
- r"""Return True if this connection is closed.
-
- .. container:: class_bases
-
- Proxied for the :class:`_engine.Connection` class
- on behalf of the :class:`_asyncio.AsyncConnection` class.
-
- """ # noqa: E501
-
- return self._proxied.closed
-
- @property
- def invalidated(self) -> Any:
- r"""Return True if this connection was invalidated.
-
- .. container:: class_bases
-
- Proxied for the :class:`_engine.Connection` class
- on behalf of the :class:`_asyncio.AsyncConnection` class.
-
- This does not indicate whether or not the connection was
- invalidated at the pool level, however
-
-
- """ # noqa: E501
-
- return self._proxied.invalidated
-
- @property
- def dialect(self) -> Dialect:
- r"""Proxy for the :attr:`_engine.Connection.dialect` attribute
- on behalf of the :class:`_asyncio.AsyncConnection` class.
-
- """ # noqa: E501
-
- return self._proxied.dialect
-
- @dialect.setter
- def dialect(self, attr: Dialect) -> None:
- self._proxied.dialect = attr
-
- @property
- def default_isolation_level(self) -> Any:
- r"""The initial-connection time isolation level associated with the
- :class:`_engine.Dialect` in use.
-
- .. container:: class_bases
-
- Proxied for the :class:`_engine.Connection` class
- on behalf of the :class:`_asyncio.AsyncConnection` class.
-
- This value is independent of the
- :paramref:`.Connection.execution_options.isolation_level` and
- :paramref:`.Engine.execution_options.isolation_level` execution
- options, and is determined by the :class:`_engine.Dialect` when the
- first connection is created, by performing a SQL query against the
- database for the current isolation level before any additional commands
- have been emitted.
-
- Calling this accessor does not invoke any new SQL queries.
-
- .. seealso::
-
- :meth:`_engine.Connection.get_isolation_level`
- - view current actual isolation level
-
- :paramref:`_sa.create_engine.isolation_level`
- - set per :class:`_engine.Engine` isolation level
-
- :paramref:`.Connection.execution_options.isolation_level`
- - set per :class:`_engine.Connection` isolation level
-
-
- """ # noqa: E501
-
- return self._proxied.default_isolation_level
-
- # END PROXY METHODS AsyncConnection
-
-
-@util.create_proxy_methods(
- Engine,
- ":class:`_engine.Engine`",
- ":class:`_asyncio.AsyncEngine`",
- classmethods=[],
- methods=[
- "clear_compiled_cache",
- "update_execution_options",
- "get_execution_options",
- ],
- attributes=["url", "pool", "dialect", "engine", "name", "driver", "echo"],
-)
-class AsyncEngine(ProxyComparable[Engine], AsyncConnectable):
- """An asyncio proxy for a :class:`_engine.Engine`.
-
- :class:`_asyncio.AsyncEngine` is acquired using the
- :func:`_asyncio.create_async_engine` function::
-
- from sqlalchemy.ext.asyncio import create_async_engine
- engine = create_async_engine("postgresql+asyncpg://user:pass@host/dbname")
-
- .. versionadded:: 1.4
-
- """ # noqa
-
- # AsyncEngine is a thin proxy; no state should be added here
- # that is not retrievable from the "sync" engine / connection, e.g.
- # current transaction, info, etc. It should be possible to
- # create a new AsyncEngine that matches this one given only the
- # "sync" elements.
- __slots__ = "sync_engine"
-
- _connection_cls: Type[AsyncConnection] = AsyncConnection
-
- sync_engine: Engine
- """Reference to the sync-style :class:`_engine.Engine` this
- :class:`_asyncio.AsyncEngine` proxies requests towards.
-
- This instance can be used as an event target.
-
- .. seealso::
-
- :ref:`asyncio_events`
- """
-
- def __init__(self, sync_engine: Engine):
- if not sync_engine.dialect.is_async:
- raise exc.InvalidRequestError(
- "The asyncio extension requires an async driver to be used. "
- f"The loaded {sync_engine.dialect.driver!r} is not async."
- )
- self.sync_engine = self._assign_proxied(sync_engine)
-
- @util.ro_non_memoized_property
- def _proxied(self) -> Engine:
- return self.sync_engine
-
- @classmethod
- def _regenerate_proxy_for_target(cls, target: Engine) -> AsyncEngine:
- return AsyncEngine(target)
-
- @contextlib.asynccontextmanager
- async def begin(self) -> AsyncIterator[AsyncConnection]:
- """Return a context manager which when entered will deliver an
- :class:`_asyncio.AsyncConnection` with an
- :class:`_asyncio.AsyncTransaction` established.
-
- E.g.::
-
- async with async_engine.begin() as conn:
- await conn.execute(
- text("insert into table (x, y, z) values (1, 2, 3)")
- )
- await conn.execute(text("my_special_procedure(5)"))
-
-
- """
- conn = self.connect()
-
- async with conn:
- async with conn.begin():
- yield conn
-
- def connect(self) -> AsyncConnection:
- """Return an :class:`_asyncio.AsyncConnection` object.
-
- The :class:`_asyncio.AsyncConnection` will procure a database
- connection from the underlying connection pool when it is entered
- as an async context manager::
-
- async with async_engine.connect() as conn:
- result = await conn.execute(select(user_table))
-
- The :class:`_asyncio.AsyncConnection` may also be started outside of a
- context manager by invoking its :meth:`_asyncio.AsyncConnection.start`
- method.
-
- """
-
- return self._connection_cls(self)
-
- async def raw_connection(self) -> PoolProxiedConnection:
- """Return a "raw" DBAPI connection from the connection pool.
-
- .. seealso::
-
- :ref:`dbapi_connections`
-
- """
- return await greenlet_spawn(self.sync_engine.raw_connection)
-
- @overload
- def execution_options(
- self,
- *,
- compiled_cache: Optional[CompiledCacheType] = ...,
- logging_token: str = ...,
- isolation_level: IsolationLevel = ...,
- insertmanyvalues_page_size: int = ...,
- schema_translate_map: Optional[SchemaTranslateMapType] = ...,
- **opt: Any,
- ) -> AsyncEngine: ...
-
- @overload
- def execution_options(self, **opt: Any) -> AsyncEngine: ...
-
- def execution_options(self, **opt: Any) -> AsyncEngine:
- """Return a new :class:`_asyncio.AsyncEngine` that will provide
- :class:`_asyncio.AsyncConnection` objects with the given execution
- options.
-
- Proxied from :meth:`_engine.Engine.execution_options`. See that
- method for details.
-
- """
-
- return AsyncEngine(self.sync_engine.execution_options(**opt))
-
- async def dispose(self, close: bool = True) -> None:
- """Dispose of the connection pool used by this
- :class:`_asyncio.AsyncEngine`.
-
- :param close: if left at its default of ``True``, has the
- effect of fully closing all **currently checked in**
- database connections. Connections that are still checked out
- will **not** be closed, however they will no longer be associated
- with this :class:`_engine.Engine`,
- so when they are closed individually, eventually the
- :class:`_pool.Pool` which they are associated with will
- be garbage collected and they will be closed out fully, if
- not already closed on checkin.
-
- If set to ``False``, the previous connection pool is de-referenced,
- and otherwise not touched in any way.
-
- .. seealso::
-
- :meth:`_engine.Engine.dispose`
-
- """
-
- await greenlet_spawn(self.sync_engine.dispose, close=close)
-
- # START PROXY METHODS AsyncEngine
-
- # code within this block is **programmatically,
- # statically generated** by tools/generate_proxy_methods.py
-
- def clear_compiled_cache(self) -> None:
- r"""Clear the compiled cache associated with the dialect.
-
- .. container:: class_bases
-
- Proxied for the :class:`_engine.Engine` class on
- behalf of the :class:`_asyncio.AsyncEngine` class.
-
- This applies **only** to the built-in cache that is established
- via the :paramref:`_engine.create_engine.query_cache_size` parameter.
- It will not impact any dictionary caches that were passed via the
- :paramref:`.Connection.execution_options.compiled_cache` parameter.
-
- .. versionadded:: 1.4
-
-
- """ # noqa: E501
-
- return self._proxied.clear_compiled_cache()
-
- def update_execution_options(self, **opt: Any) -> None:
- r"""Update the default execution_options dictionary
- of this :class:`_engine.Engine`.
-
- .. container:: class_bases
-
- Proxied for the :class:`_engine.Engine` class on
- behalf of the :class:`_asyncio.AsyncEngine` class.
-
- The given keys/values in \**opt are added to the
- default execution options that will be used for
- all connections. The initial contents of this dictionary
- can be sent via the ``execution_options`` parameter
- to :func:`_sa.create_engine`.
-
- .. seealso::
-
- :meth:`_engine.Connection.execution_options`
-
- :meth:`_engine.Engine.execution_options`
-
-
- """ # noqa: E501
-
- return self._proxied.update_execution_options(**opt)
-
- def get_execution_options(self) -> _ExecuteOptions:
- r"""Get the non-SQL options which will take effect during execution.
-
- .. container:: class_bases
-
- Proxied for the :class:`_engine.Engine` class on
- behalf of the :class:`_asyncio.AsyncEngine` class.
-
- .. versionadded: 1.3
-
- .. seealso::
-
- :meth:`_engine.Engine.execution_options`
-
- """ # noqa: E501
-
- return self._proxied.get_execution_options()
-
- @property
- def url(self) -> URL:
- r"""Proxy for the :attr:`_engine.Engine.url` attribute
- on behalf of the :class:`_asyncio.AsyncEngine` class.
-
- """ # noqa: E501
-
- return self._proxied.url
-
- @url.setter
- def url(self, attr: URL) -> None:
- self._proxied.url = attr
-
- @property
- def pool(self) -> Pool:
- r"""Proxy for the :attr:`_engine.Engine.pool` attribute
- on behalf of the :class:`_asyncio.AsyncEngine` class.
-
- """ # noqa: E501
-
- return self._proxied.pool
-
- @pool.setter
- def pool(self, attr: Pool) -> None:
- self._proxied.pool = attr
-
- @property
- def dialect(self) -> Dialect:
- r"""Proxy for the :attr:`_engine.Engine.dialect` attribute
- on behalf of the :class:`_asyncio.AsyncEngine` class.
-
- """ # noqa: E501
-
- return self._proxied.dialect
-
- @dialect.setter
- def dialect(self, attr: Dialect) -> None:
- self._proxied.dialect = attr
-
- @property
- def engine(self) -> Any:
- r"""Returns this :class:`.Engine`.
-
- .. container:: class_bases
-
- Proxied for the :class:`_engine.Engine` class
- on behalf of the :class:`_asyncio.AsyncEngine` class.
-
- Used for legacy schemes that accept :class:`.Connection` /
- :class:`.Engine` objects within the same variable.
-
-
- """ # noqa: E501
-
- return self._proxied.engine
-
- @property
- def name(self) -> Any:
- r"""String name of the :class:`~sqlalchemy.engine.interfaces.Dialect`
- in use by this :class:`Engine`.
-
- .. container:: class_bases
-
- Proxied for the :class:`_engine.Engine` class
- on behalf of the :class:`_asyncio.AsyncEngine` class.
-
-
- """ # noqa: E501
-
- return self._proxied.name
-
- @property
- def driver(self) -> Any:
- r"""Driver name of the :class:`~sqlalchemy.engine.interfaces.Dialect`
- in use by this :class:`Engine`.
-
- .. container:: class_bases
-
- Proxied for the :class:`_engine.Engine` class
- on behalf of the :class:`_asyncio.AsyncEngine` class.
-
-
- """ # noqa: E501
-
- return self._proxied.driver
-
- @property
- def echo(self) -> Any:
- r"""When ``True``, enable log output for this element.
-
- .. container:: class_bases
-
- Proxied for the :class:`_engine.Engine` class
- on behalf of the :class:`_asyncio.AsyncEngine` class.
-
- This has the effect of setting the Python logging level for the namespace
- of this element's class and object reference. A value of boolean ``True``
- indicates that the loglevel ``logging.INFO`` will be set for the logger,
- whereas the string value ``debug`` will set the loglevel to
- ``logging.DEBUG``.
-
- """ # noqa: E501
-
- return self._proxied.echo
-
- @echo.setter
- def echo(self, attr: Any) -> None:
- self._proxied.echo = attr
-
- # END PROXY METHODS AsyncEngine
-
-
-class AsyncTransaction(
- ProxyComparable[Transaction], StartableContext["AsyncTransaction"]
-):
- """An asyncio proxy for a :class:`_engine.Transaction`."""
-
- __slots__ = ("connection", "sync_transaction", "nested")
-
- sync_transaction: Optional[Transaction]
- connection: AsyncConnection
- nested: bool
-
- def __init__(self, connection: AsyncConnection, nested: bool = False):
- self.connection = connection
- self.sync_transaction = None
- self.nested = nested
-
- @classmethod
- def _regenerate_proxy_for_target(
- cls, target: Transaction
- ) -> AsyncTransaction:
- sync_connection = target.connection
- sync_transaction = target
- nested = isinstance(target, NestedTransaction)
-
- async_connection = AsyncConnection._retrieve_proxy_for_target(
- sync_connection
- )
- assert async_connection is not None
-
- obj = cls.__new__(cls)
- obj.connection = async_connection
- obj.sync_transaction = obj._assign_proxied(sync_transaction)
- obj.nested = nested
- return obj
-
- @util.ro_non_memoized_property
- def _proxied(self) -> Transaction:
- if not self.sync_transaction:
- self._raise_for_not_started()
- return self.sync_transaction
-
- @property
- def is_valid(self) -> bool:
- return self._proxied.is_valid
-
- @property
- def is_active(self) -> bool:
- return self._proxied.is_active
-
- async def close(self) -> None:
- """Close this :class:`.AsyncTransaction`.
-
- If this transaction is the base transaction in a begin/commit
- nesting, the transaction will rollback(). Otherwise, the
- method returns.
-
- This is used to cancel a Transaction without affecting the scope of
- an enclosing transaction.
-
- """
- await greenlet_spawn(self._proxied.close)
-
- async def rollback(self) -> None:
- """Roll back this :class:`.AsyncTransaction`."""
- await greenlet_spawn(self._proxied.rollback)
-
- async def commit(self) -> None:
- """Commit this :class:`.AsyncTransaction`."""
-
- await greenlet_spawn(self._proxied.commit)
-
- async def start(self, is_ctxmanager: bool = False) -> AsyncTransaction:
- """Start this :class:`_asyncio.AsyncTransaction` object's context
- outside of using a Python ``with:`` block.
-
- """
-
- self.sync_transaction = self._assign_proxied(
- await greenlet_spawn(
- self.connection._proxied.begin_nested
- if self.nested
- else self.connection._proxied.begin
- )
- )
- if is_ctxmanager:
- self.sync_transaction.__enter__()
- return self
-
- async def __aexit__(self, type_: Any, value: Any, traceback: Any) -> None:
- await greenlet_spawn(self._proxied.__exit__, type_, value, traceback)
-
-
-@overload
-def _get_sync_engine_or_connection(async_engine: AsyncEngine) -> Engine: ...
-
-
-@overload
-def _get_sync_engine_or_connection(
- async_engine: AsyncConnection,
-) -> Connection: ...
-
-
-def _get_sync_engine_or_connection(
- async_engine: Union[AsyncEngine, AsyncConnection]
-) -> Union[Engine, Connection]:
- if isinstance(async_engine, AsyncConnection):
- return async_engine._proxied
-
- try:
- return async_engine.sync_engine
- except AttributeError as e:
- raise exc.ArgumentError(
- "AsyncEngine expected, got %r" % async_engine
- ) from e
-
-
-@inspection._inspects(AsyncConnection)
-def _no_insp_for_async_conn_yet(
- subject: AsyncConnection, # noqa: U100
-) -> NoReturn:
- raise exc.NoInspectionAvailable(
- "Inspection on an AsyncConnection is currently not supported. "
- "Please use ``run_sync`` to pass a callable where it's possible "
- "to call ``inspect`` on the passed connection.",
- code="xd3s",
- )
-
-
-@inspection._inspects(AsyncEngine)
-def _no_insp_for_async_engine_xyet(
- subject: AsyncEngine, # noqa: U100
-) -> NoReturn:
- raise exc.NoInspectionAvailable(
- "Inspection on an AsyncEngine is currently not supported. "
- "Please obtain a connection then use ``conn.run_sync`` to pass a "
- "callable where it's possible to call ``inspect`` on the "
- "passed connection.",
- code="xd3s",
- )
diff --git a/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/exc.py b/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/exc.py
deleted file mode 100644
index 1cf6f36..0000000
--- a/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/exc.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# ext/asyncio/exc.py
-# Copyright (C) 2020-2024 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
-
-from ... import exc
-
-
-class AsyncMethodRequired(exc.InvalidRequestError):
- """an API can't be used because its result would not be
- compatible with async"""
-
-
-class AsyncContextNotStarted(exc.InvalidRequestError):
- """a startable context manager has not been started."""
-
-
-class AsyncContextAlreadyStarted(exc.InvalidRequestError):
- """a startable context manager is already started."""
diff --git a/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/result.py b/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/result.py
deleted file mode 100644
index 7dcbe32..0000000
--- a/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/result.py
+++ /dev/null
@@ -1,961 +0,0 @@
-# ext/asyncio/result.py
-# Copyright (C) 2020-2024 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
-from __future__ import annotations
-
-import operator
-from typing import Any
-from typing import AsyncIterator
-from typing import Optional
-from typing import overload
-from typing import Sequence
-from typing import Tuple
-from typing import TYPE_CHECKING
-from typing import TypeVar
-
-from . import exc as async_exc
-from ... import util
-from ...engine import Result
-from ...engine.result import _NO_ROW
-from ...engine.result import _R
-from ...engine.result import _WithKeys
-from ...engine.result import FilterResult
-from ...engine.result import FrozenResult
-from ...engine.result import ResultMetaData
-from ...engine.row import Row
-from ...engine.row import RowMapping
-from ...sql.base import _generative
-from ...util.concurrency import greenlet_spawn
-from ...util.typing import Literal
-from ...util.typing import Self
-
-if TYPE_CHECKING:
- from ...engine import CursorResult
- from ...engine.result import _KeyIndexType
- from ...engine.result import _UniqueFilterType
-
-_T = TypeVar("_T", bound=Any)
-_TP = TypeVar("_TP", bound=Tuple[Any, ...])
-
-
-class AsyncCommon(FilterResult[_R]):
- __slots__ = ()
-
- _real_result: Result[Any]
- _metadata: ResultMetaData
-
- async def close(self) -> None: # type: ignore[override]
- """Close this result."""
-
- await greenlet_spawn(self._real_result.close)
-
- @property
- def closed(self) -> bool:
- """proxies the .closed attribute of the underlying result object,
- if any, else raises ``AttributeError``.
-
- .. versionadded:: 2.0.0b3
-
- """
- return self._real_result.closed
-
-
-class AsyncResult(_WithKeys, AsyncCommon[Row[_TP]]):
- """An asyncio wrapper around a :class:`_result.Result` object.
-
- The :class:`_asyncio.AsyncResult` only applies to statement executions that
- use a server-side cursor. It is returned only from the
- :meth:`_asyncio.AsyncConnection.stream` and
- :meth:`_asyncio.AsyncSession.stream` methods.
-
- .. note:: As is the case with :class:`_engine.Result`, this object is
- used for ORM results returned by :meth:`_asyncio.AsyncSession.execute`,
- which can yield instances of ORM mapped objects either individually or
- within tuple-like rows. Note that these result objects do not
- deduplicate instances or rows automatically as is the case with the
- legacy :class:`_orm.Query` object. For in-Python de-duplication of
- instances or rows, use the :meth:`_asyncio.AsyncResult.unique` modifier
- method.
-
- .. versionadded:: 1.4
-
- """
-
- __slots__ = ()
-
- _real_result: Result[_TP]
-
- def __init__(self, real_result: Result[_TP]):
- self._real_result = real_result
-
- self._metadata = real_result._metadata
- self._unique_filter_state = real_result._unique_filter_state
- self._post_creational_filter = None
-
- # BaseCursorResult pre-generates the "_row_getter". Use that
- # if available rather than building a second one
- if "_row_getter" in real_result.__dict__:
- self._set_memoized_attribute(
- "_row_getter", real_result.__dict__["_row_getter"]
- )
-
- @property
- def t(self) -> AsyncTupleResult[_TP]:
- """Apply a "typed tuple" typing filter to returned rows.
-
- The :attr:`_asyncio.AsyncResult.t` attribute is a synonym for
- calling the :meth:`_asyncio.AsyncResult.tuples` method.
-
- .. versionadded:: 2.0
-
- """
- return self # type: ignore
-
- def tuples(self) -> AsyncTupleResult[_TP]:
- """Apply a "typed tuple" typing filter to returned rows.
-
- This method returns the same :class:`_asyncio.AsyncResult` object
- at runtime,
- however annotates as returning a :class:`_asyncio.AsyncTupleResult`
- object that will indicate to :pep:`484` typing tools that plain typed
- ``Tuple`` instances are returned rather than rows. This allows
- tuple unpacking and ``__getitem__`` access of :class:`_engine.Row`
- objects to by typed, for those cases where the statement invoked
- itself included typing information.
-
- .. versionadded:: 2.0
-
- :return: the :class:`_result.AsyncTupleResult` type at typing time.
-
- .. seealso::
-
- :attr:`_asyncio.AsyncResult.t` - shorter synonym
-
- :attr:`_engine.Row.t` - :class:`_engine.Row` version
-
- """
-
- return self # type: ignore
-
- @_generative
- def unique(self, strategy: Optional[_UniqueFilterType] = None) -> Self:
- """Apply unique filtering to the objects returned by this
- :class:`_asyncio.AsyncResult`.
-
- Refer to :meth:`_engine.Result.unique` in the synchronous
- SQLAlchemy API for a complete behavioral description.
-
- """
- self._unique_filter_state = (set(), strategy)
- return self
-
- def columns(self, *col_expressions: _KeyIndexType) -> Self:
- r"""Establish the columns that should be returned in each row.
-
- Refer to :meth:`_engine.Result.columns` in the synchronous
- SQLAlchemy API for a complete behavioral description.
-
- """
- return self._column_slices(col_expressions)
-
- async def partitions(
- self, size: Optional[int] = None
- ) -> AsyncIterator[Sequence[Row[_TP]]]:
- """Iterate through sub-lists of rows of the size given.
-
- An async iterator is returned::
-
- async def scroll_results(connection):
- result = await connection.stream(select(users_table))
-
- async for partition in result.partitions(100):
- print("list of rows: %s" % partition)
-
- Refer to :meth:`_engine.Result.partitions` in the synchronous
- SQLAlchemy API for a complete behavioral description.
-
- """
-
- getter = self._manyrow_getter
-
- while True:
- partition = await greenlet_spawn(getter, self, size)
- if partition:
- yield partition
- else:
- break
-
- async def fetchall(self) -> Sequence[Row[_TP]]:
- """A synonym for the :meth:`_asyncio.AsyncResult.all` method.
-
- .. versionadded:: 2.0
-
- """
-
- return await greenlet_spawn(self._allrows)
-
- async def fetchone(self) -> Optional[Row[_TP]]:
- """Fetch one row.
-
- When all rows are exhausted, returns None.
-
- This method is provided for backwards compatibility with
- SQLAlchemy 1.x.x.
-
- To fetch the first row of a result only, use the
- :meth:`_asyncio.AsyncResult.first` method. To iterate through all
- rows, iterate the :class:`_asyncio.AsyncResult` object directly.
-
- :return: a :class:`_engine.Row` object if no filters are applied,
- or ``None`` if no rows remain.
-
- """
- row = await greenlet_spawn(self._onerow_getter, self)
- if row is _NO_ROW:
- return None
- else:
- return row
-
- async def fetchmany(
- self, size: Optional[int] = None
- ) -> Sequence[Row[_TP]]:
- """Fetch many rows.
-
- When all rows are exhausted, returns an empty list.
-
- This method is provided for backwards compatibility with
- SQLAlchemy 1.x.x.
-
- To fetch rows in groups, use the
- :meth:`._asyncio.AsyncResult.partitions` method.
-
- :return: a list of :class:`_engine.Row` objects.
-
- .. seealso::
-
- :meth:`_asyncio.AsyncResult.partitions`
-
- """
-
- return await greenlet_spawn(self._manyrow_getter, self, size)
-
- async def all(self) -> Sequence[Row[_TP]]:
- """Return all rows in a list.
-
- Closes the result set after invocation. Subsequent invocations
- will return an empty list.
-
- :return: a list of :class:`_engine.Row` objects.
-
- """
-
- return await greenlet_spawn(self._allrows)
-
- def __aiter__(self) -> AsyncResult[_TP]:
- return self
-
- async def __anext__(self) -> Row[_TP]:
- row = await greenlet_spawn(self._onerow_getter, self)
- if row is _NO_ROW:
- raise StopAsyncIteration()
- else:
- return row
-
- async def first(self) -> Optional[Row[_TP]]:
- """Fetch the first row or ``None`` if no row is present.
-
- Closes the result set and discards remaining rows.
-
- .. note:: This method returns one **row**, e.g. tuple, by default.
- To return exactly one single scalar value, that is, the first
- column of the first row, use the
- :meth:`_asyncio.AsyncResult.scalar` method,
- or combine :meth:`_asyncio.AsyncResult.scalars` and
- :meth:`_asyncio.AsyncResult.first`.
-
- Additionally, in contrast to the behavior of the legacy ORM
- :meth:`_orm.Query.first` method, **no limit is applied** to the
- SQL query which was invoked to produce this
- :class:`_asyncio.AsyncResult`;
- for a DBAPI driver that buffers results in memory before yielding
- rows, all rows will be sent to the Python process and all but
- the first row will be discarded.
-
- .. seealso::
-
- :ref:`migration_20_unify_select`
-
- :return: a :class:`_engine.Row` object, or None
- if no rows remain.
-
- .. seealso::
-
- :meth:`_asyncio.AsyncResult.scalar`
-
- :meth:`_asyncio.AsyncResult.one`
-
- """
- return await greenlet_spawn(self._only_one_row, False, False, False)
-
- async def one_or_none(self) -> Optional[Row[_TP]]:
- """Return at most one result or raise an exception.
-
- Returns ``None`` if the result has no rows.
- Raises :class:`.MultipleResultsFound`
- if multiple rows are returned.
-
- .. versionadded:: 1.4
-
- :return: The first :class:`_engine.Row` or ``None`` if no row
- is available.
-
- :raises: :class:`.MultipleResultsFound`
-
- .. seealso::
-
- :meth:`_asyncio.AsyncResult.first`
-
- :meth:`_asyncio.AsyncResult.one`
-
- """
- return await greenlet_spawn(self._only_one_row, True, False, False)
-
- @overload
- async def scalar_one(self: AsyncResult[Tuple[_T]]) -> _T: ...
-
- @overload
- async def scalar_one(self) -> Any: ...
-
- async def scalar_one(self) -> Any:
- """Return exactly one scalar result or raise an exception.
-
- This is equivalent to calling :meth:`_asyncio.AsyncResult.scalars` and
- then :meth:`_asyncio.AsyncResult.one`.
-
- .. seealso::
-
- :meth:`_asyncio.AsyncResult.one`
-
- :meth:`_asyncio.AsyncResult.scalars`
-
- """
- return await greenlet_spawn(self._only_one_row, True, True, True)
-
- @overload
- async def scalar_one_or_none(
- self: AsyncResult[Tuple[_T]],
- ) -> Optional[_T]: ...
-
- @overload
- async def scalar_one_or_none(self) -> Optional[Any]: ...
-
- async def scalar_one_or_none(self) -> Optional[Any]:
- """Return exactly one scalar result or ``None``.
-
- This is equivalent to calling :meth:`_asyncio.AsyncResult.scalars` and
- then :meth:`_asyncio.AsyncResult.one_or_none`.
-
- .. seealso::
-
- :meth:`_asyncio.AsyncResult.one_or_none`
-
- :meth:`_asyncio.AsyncResult.scalars`
-
- """
- return await greenlet_spawn(self._only_one_row, True, False, True)
-
- async def one(self) -> Row[_TP]:
- """Return exactly one row or raise an exception.
-
- Raises :class:`.NoResultFound` if the result returns no
- rows, or :class:`.MultipleResultsFound` if multiple rows
- would be returned.
-
- .. note:: This method returns one **row**, e.g. tuple, by default.
- To return exactly one single scalar value, that is, the first
- column of the first row, use the
- :meth:`_asyncio.AsyncResult.scalar_one` method, or combine
- :meth:`_asyncio.AsyncResult.scalars` and
- :meth:`_asyncio.AsyncResult.one`.
-
- .. versionadded:: 1.4
-
- :return: The first :class:`_engine.Row`.
-
- :raises: :class:`.MultipleResultsFound`, :class:`.NoResultFound`
-
- .. seealso::
-
- :meth:`_asyncio.AsyncResult.first`
-
- :meth:`_asyncio.AsyncResult.one_or_none`
-
- :meth:`_asyncio.AsyncResult.scalar_one`
-
- """
- return await greenlet_spawn(self._only_one_row, True, True, False)
-
- @overload
- async def scalar(self: AsyncResult[Tuple[_T]]) -> Optional[_T]: ...
-
- @overload
- async def scalar(self) -> Any: ...
-
- async def scalar(self) -> Any:
- """Fetch the first column of the first row, and close the result set.
-
- Returns ``None`` if there are no rows to fetch.
-
- No validation is performed to test if additional rows remain.
-
- After calling this method, the object is fully closed,
- e.g. the :meth:`_engine.CursorResult.close`
- method will have been called.
-
- :return: a Python scalar value, or ``None`` if no rows remain.
-
- """
- return await greenlet_spawn(self._only_one_row, False, False, True)
-
- async def freeze(self) -> FrozenResult[_TP]:
- """Return a callable object that will produce copies of this
- :class:`_asyncio.AsyncResult` when invoked.
-
- The callable object returned is an instance of
- :class:`_engine.FrozenResult`.
-
- This is used for result set caching. The method must be called
- on the result when it has been unconsumed, and calling the method
- will consume the result fully. When the :class:`_engine.FrozenResult`
- is retrieved from a cache, it can be called any number of times where
- it will produce a new :class:`_engine.Result` object each time
- against its stored set of rows.
-
- .. seealso::
-
- :ref:`do_orm_execute_re_executing` - example usage within the
- ORM to implement a result-set cache.
-
- """
-
- return await greenlet_spawn(FrozenResult, self)
-
- @overload
- def scalars(
- self: AsyncResult[Tuple[_T]], index: Literal[0]
- ) -> AsyncScalarResult[_T]: ...
-
- @overload
- def scalars(self: AsyncResult[Tuple[_T]]) -> AsyncScalarResult[_T]: ...
-
- @overload
- def scalars(self, index: _KeyIndexType = 0) -> AsyncScalarResult[Any]: ...
-
- def scalars(self, index: _KeyIndexType = 0) -> AsyncScalarResult[Any]:
- """Return an :class:`_asyncio.AsyncScalarResult` filtering object which
- will return single elements rather than :class:`_row.Row` objects.
-
- Refer to :meth:`_result.Result.scalars` in the synchronous
- SQLAlchemy API for a complete behavioral description.
-
- :param index: integer or row key indicating the column to be fetched
- from each row, defaults to ``0`` indicating the first column.
-
- :return: a new :class:`_asyncio.AsyncScalarResult` filtering object
- referring to this :class:`_asyncio.AsyncResult` object.
-
- """
- return AsyncScalarResult(self._real_result, index)
-
- def mappings(self) -> AsyncMappingResult:
- """Apply a mappings filter to returned rows, returning an instance of
- :class:`_asyncio.AsyncMappingResult`.
-
- When this filter is applied, fetching rows will return
- :class:`_engine.RowMapping` objects instead of :class:`_engine.Row`
- objects.
-
- :return: a new :class:`_asyncio.AsyncMappingResult` filtering object
- referring to the underlying :class:`_result.Result` object.
-
- """
-
- return AsyncMappingResult(self._real_result)
-
-
-class AsyncScalarResult(AsyncCommon[_R]):
- """A wrapper for a :class:`_asyncio.AsyncResult` that returns scalar values
- rather than :class:`_row.Row` values.
-
- The :class:`_asyncio.AsyncScalarResult` object is acquired by calling the
- :meth:`_asyncio.AsyncResult.scalars` method.
-
- Refer to the :class:`_result.ScalarResult` object in the synchronous
- SQLAlchemy API for a complete behavioral description.
-
- .. versionadded:: 1.4
-
- """
-
- __slots__ = ()
-
- _generate_rows = False
-
- def __init__(self, real_result: Result[Any], index: _KeyIndexType):
- self._real_result = real_result
-
- if real_result._source_supports_scalars:
- self._metadata = real_result._metadata
- self._post_creational_filter = None
- else:
- self._metadata = real_result._metadata._reduce([index])
- self._post_creational_filter = operator.itemgetter(0)
-
- self._unique_filter_state = real_result._unique_filter_state
-
- def unique(
- self,
- strategy: Optional[_UniqueFilterType] = None,
- ) -> Self:
- """Apply unique filtering to the objects returned by this
- :class:`_asyncio.AsyncScalarResult`.
-
- See :meth:`_asyncio.AsyncResult.unique` for usage details.
-
- """
- self._unique_filter_state = (set(), strategy)
- return self
-
- async def partitions(
- self, size: Optional[int] = None
- ) -> AsyncIterator[Sequence[_R]]:
- """Iterate through sub-lists of elements of the size given.
-
- Equivalent to :meth:`_asyncio.AsyncResult.partitions` except that
- scalar values, rather than :class:`_engine.Row` objects,
- are returned.
-
- """
-
- getter = self._manyrow_getter
-
- while True:
- partition = await greenlet_spawn(getter, self, size)
- if partition:
- yield partition
- else:
- break
-
- async def fetchall(self) -> Sequence[_R]:
- """A synonym for the :meth:`_asyncio.AsyncScalarResult.all` method."""
-
- return await greenlet_spawn(self._allrows)
-
- async def fetchmany(self, size: Optional[int] = None) -> Sequence[_R]:
- """Fetch many objects.
-
- Equivalent to :meth:`_asyncio.AsyncResult.fetchmany` except that
- scalar values, rather than :class:`_engine.Row` objects,
- are returned.
-
- """
- return await greenlet_spawn(self._manyrow_getter, self, size)
-
- async def all(self) -> Sequence[_R]:
- """Return all scalar values in a list.
-
- Equivalent to :meth:`_asyncio.AsyncResult.all` except that
- scalar values, rather than :class:`_engine.Row` objects,
- are returned.
-
- """
- return await greenlet_spawn(self._allrows)
-
- def __aiter__(self) -> AsyncScalarResult[_R]:
- return self
-
- async def __anext__(self) -> _R:
- row = await greenlet_spawn(self._onerow_getter, self)
- if row is _NO_ROW:
- raise StopAsyncIteration()
- else:
- return row
-
- async def first(self) -> Optional[_R]:
- """Fetch the first object or ``None`` if no object is present.
-
- Equivalent to :meth:`_asyncio.AsyncResult.first` except that
- scalar values, rather than :class:`_engine.Row` objects,
- are returned.
-
- """
- return await greenlet_spawn(self._only_one_row, False, False, False)
-
- async def one_or_none(self) -> Optional[_R]:
- """Return at most one object or raise an exception.
-
- Equivalent to :meth:`_asyncio.AsyncResult.one_or_none` except that
- scalar values, rather than :class:`_engine.Row` objects,
- are returned.
-
- """
- return await greenlet_spawn(self._only_one_row, True, False, False)
-
- async def one(self) -> _R:
- """Return exactly one object or raise an exception.
-
- Equivalent to :meth:`_asyncio.AsyncResult.one` except that
- scalar values, rather than :class:`_engine.Row` objects,
- are returned.
-
- """
- return await greenlet_spawn(self._only_one_row, True, True, False)
-
-
-class AsyncMappingResult(_WithKeys, AsyncCommon[RowMapping]):
- """A wrapper for a :class:`_asyncio.AsyncResult` that returns dictionary
- values rather than :class:`_engine.Row` values.
-
- The :class:`_asyncio.AsyncMappingResult` object is acquired by calling the
- :meth:`_asyncio.AsyncResult.mappings` method.
-
- Refer to the :class:`_result.MappingResult` object in the synchronous
- SQLAlchemy API for a complete behavioral description.
-
- .. versionadded:: 1.4
-
- """
-
- __slots__ = ()
-
- _generate_rows = True
-
- _post_creational_filter = operator.attrgetter("_mapping")
-
- def __init__(self, result: Result[Any]):
- self._real_result = result
- self._unique_filter_state = result._unique_filter_state
- self._metadata = result._metadata
- if result._source_supports_scalars:
- self._metadata = self._metadata._reduce([0])
-
- def unique(
- self,
- strategy: Optional[_UniqueFilterType] = None,
- ) -> Self:
- """Apply unique filtering to the objects returned by this
- :class:`_asyncio.AsyncMappingResult`.
-
- See :meth:`_asyncio.AsyncResult.unique` for usage details.
-
- """
- self._unique_filter_state = (set(), strategy)
- return self
-
- def columns(self, *col_expressions: _KeyIndexType) -> Self:
- r"""Establish the columns that should be returned in each row."""
- return self._column_slices(col_expressions)
-
- async def partitions(
- self, size: Optional[int] = None
- ) -> AsyncIterator[Sequence[RowMapping]]:
- """Iterate through sub-lists of elements of the size given.
-
- Equivalent to :meth:`_asyncio.AsyncResult.partitions` except that
- :class:`_engine.RowMapping` values, rather than :class:`_engine.Row`
- objects, are returned.
-
- """
-
- getter = self._manyrow_getter
-
- while True:
- partition = await greenlet_spawn(getter, self, size)
- if partition:
- yield partition
- else:
- break
-
- async def fetchall(self) -> Sequence[RowMapping]:
- """A synonym for the :meth:`_asyncio.AsyncMappingResult.all` method."""
-
- return await greenlet_spawn(self._allrows)
-
- async def fetchone(self) -> Optional[RowMapping]:
- """Fetch one object.
-
- Equivalent to :meth:`_asyncio.AsyncResult.fetchone` except that
- :class:`_engine.RowMapping` values, rather than :class:`_engine.Row`
- objects, are returned.
-
- """
-
- row = await greenlet_spawn(self._onerow_getter, self)
- if row is _NO_ROW:
- return None
- else:
- return row
-
- async def fetchmany(
- self, size: Optional[int] = None
- ) -> Sequence[RowMapping]:
- """Fetch many rows.
-
- Equivalent to :meth:`_asyncio.AsyncResult.fetchmany` except that
- :class:`_engine.RowMapping` values, rather than :class:`_engine.Row`
- objects, are returned.
-
- """
-
- return await greenlet_spawn(self._manyrow_getter, self, size)
-
- async def all(self) -> Sequence[RowMapping]:
- """Return all rows in a list.
-
- Equivalent to :meth:`_asyncio.AsyncResult.all` except that
- :class:`_engine.RowMapping` values, rather than :class:`_engine.Row`
- objects, are returned.
-
- """
-
- return await greenlet_spawn(self._allrows)
-
- def __aiter__(self) -> AsyncMappingResult:
- return self
-
- async def __anext__(self) -> RowMapping:
- row = await greenlet_spawn(self._onerow_getter, self)
- if row is _NO_ROW:
- raise StopAsyncIteration()
- else:
- return row
-
- async def first(self) -> Optional[RowMapping]:
- """Fetch the first object or ``None`` if no object is present.
-
- Equivalent to :meth:`_asyncio.AsyncResult.first` except that
- :class:`_engine.RowMapping` values, rather than :class:`_engine.Row`
- objects, are returned.
-
- """
- return await greenlet_spawn(self._only_one_row, False, False, False)
-
- async def one_or_none(self) -> Optional[RowMapping]:
- """Return at most one object or raise an exception.
-
- Equivalent to :meth:`_asyncio.AsyncResult.one_or_none` except that
- :class:`_engine.RowMapping` values, rather than :class:`_engine.Row`
- objects, are returned.
-
- """
- return await greenlet_spawn(self._only_one_row, True, False, False)
-
- async def one(self) -> RowMapping:
- """Return exactly one object or raise an exception.
-
- Equivalent to :meth:`_asyncio.AsyncResult.one` except that
- :class:`_engine.RowMapping` values, rather than :class:`_engine.Row`
- objects, are returned.
-
- """
- return await greenlet_spawn(self._only_one_row, True, True, False)
-
-
-class AsyncTupleResult(AsyncCommon[_R], util.TypingOnly):
- """A :class:`_asyncio.AsyncResult` that's typed as returning plain
- Python tuples instead of rows.
-
- Since :class:`_engine.Row` acts like a tuple in every way already,
- this class is a typing only class, regular :class:`_asyncio.AsyncResult` is
- still used at runtime.
-
- """
-
- __slots__ = ()
-
- if TYPE_CHECKING:
-
- async def partitions(
- self, size: Optional[int] = None
- ) -> AsyncIterator[Sequence[_R]]:
- """Iterate through sub-lists of elements of the size given.
-
- Equivalent to :meth:`_result.Result.partitions` except that
- tuple values, rather than :class:`_engine.Row` objects,
- are returned.
-
- """
- ...
-
- async def fetchone(self) -> Optional[_R]:
- """Fetch one tuple.
-
- Equivalent to :meth:`_result.Result.fetchone` except that
- tuple values, rather than :class:`_engine.Row`
- objects, are returned.
-
- """
- ...
-
- async def fetchall(self) -> Sequence[_R]:
- """A synonym for the :meth:`_engine.ScalarResult.all` method."""
- ...
-
- async def fetchmany(self, size: Optional[int] = None) -> Sequence[_R]:
- """Fetch many objects.
-
- Equivalent to :meth:`_result.Result.fetchmany` except that
- tuple values, rather than :class:`_engine.Row` objects,
- are returned.
-
- """
- ...
-
- async def all(self) -> Sequence[_R]: # noqa: A001
- """Return all scalar values in a list.
-
- Equivalent to :meth:`_result.Result.all` except that
- tuple values, rather than :class:`_engine.Row` objects,
- are returned.
-
- """
- ...
-
- async def __aiter__(self) -> AsyncIterator[_R]: ...
-
- async def __anext__(self) -> _R: ...
-
- async def first(self) -> Optional[_R]:
- """Fetch the first object or ``None`` if no object is present.
-
- Equivalent to :meth:`_result.Result.first` except that
- tuple values, rather than :class:`_engine.Row` objects,
- are returned.
-
-
- """
- ...
-
- async def one_or_none(self) -> Optional[_R]:
- """Return at most one object or raise an exception.
-
- Equivalent to :meth:`_result.Result.one_or_none` except that
- tuple values, rather than :class:`_engine.Row` objects,
- are returned.
-
- """
- ...
-
- async def one(self) -> _R:
- """Return exactly one object or raise an exception.
-
- Equivalent to :meth:`_result.Result.one` except that
- tuple values, rather than :class:`_engine.Row` objects,
- are returned.
-
- """
- ...
-
- @overload
- async def scalar_one(self: AsyncTupleResult[Tuple[_T]]) -> _T: ...
-
- @overload
- async def scalar_one(self) -> Any: ...
-
- async def scalar_one(self) -> Any:
- """Return exactly one scalar result or raise an exception.
-
- This is equivalent to calling :meth:`_engine.Result.scalars`
- and then :meth:`_engine.Result.one`.
-
- .. seealso::
-
- :meth:`_engine.Result.one`
-
- :meth:`_engine.Result.scalars`
-
- """
- ...
-
- @overload
- async def scalar_one_or_none(
- self: AsyncTupleResult[Tuple[_T]],
- ) -> Optional[_T]: ...
-
- @overload
- async def scalar_one_or_none(self) -> Optional[Any]: ...
-
- async def scalar_one_or_none(self) -> Optional[Any]:
- """Return exactly one or no scalar result.
-
- This is equivalent to calling :meth:`_engine.Result.scalars`
- and then :meth:`_engine.Result.one_or_none`.
-
- .. seealso::
-
- :meth:`_engine.Result.one_or_none`
-
- :meth:`_engine.Result.scalars`
-
- """
- ...
-
- @overload
- async def scalar(
- self: AsyncTupleResult[Tuple[_T]],
- ) -> Optional[_T]: ...
-
- @overload
- async def scalar(self) -> Any: ...
-
- async def scalar(self) -> Any:
- """Fetch the first column of the first row, and close the result
- set.
-
- Returns ``None`` if there are no rows to fetch.
-
- No validation is performed to test if additional rows remain.
-
- After calling this method, the object is fully closed,
- e.g. the :meth:`_engine.CursorResult.close`
- method will have been called.
-
- :return: a Python scalar value , or ``None`` if no rows remain.
-
- """
- ...
-
-
-_RT = TypeVar("_RT", bound="Result[Any]")
-
-
-async def _ensure_sync_result(result: _RT, calling_method: Any) -> _RT:
- cursor_result: CursorResult[Any]
-
- try:
- is_cursor = result._is_cursor
- except AttributeError:
- # legacy execute(DefaultGenerator) case
- return result
-
- if not is_cursor:
- cursor_result = getattr(result, "raw", None) # type: ignore
- else:
- cursor_result = result # type: ignore
- if cursor_result and cursor_result.context._is_server_side:
- await greenlet_spawn(cursor_result.close)
- raise async_exc.AsyncMethodRequired(
- "Can't use the %s.%s() method with a "
- "server-side cursor. "
- "Use the %s.stream() method for an async "
- "streaming result set."
- % (
- calling_method.__self__.__class__.__name__,
- calling_method.__name__,
- calling_method.__self__.__class__.__name__,
- )
- )
- return result
diff --git a/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/scoping.py b/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/scoping.py
deleted file mode 100644
index e879a16..0000000
--- a/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/scoping.py
+++ /dev/null
@@ -1,1614 +0,0 @@
-# ext/asyncio/scoping.py
-# Copyright (C) 2005-2024 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
-
-from __future__ import annotations
-
-from typing import Any
-from typing import Callable
-from typing import Generic
-from typing import Iterable
-from typing import Iterator
-from typing import Optional
-from typing import overload
-from typing import Sequence
-from typing import Tuple
-from typing import Type
-from typing import TYPE_CHECKING
-from typing import TypeVar
-from typing import Union
-
-from .session import _AS
-from .session import async_sessionmaker
-from .session import AsyncSession
-from ... import exc as sa_exc
-from ... import util
-from ...orm.session import Session
-from ...util import create_proxy_methods
-from ...util import ScopedRegistry
-from ...util import warn
-from ...util import warn_deprecated
-
-if TYPE_CHECKING:
- from .engine import AsyncConnection
- from .result import AsyncResult
- from .result import AsyncScalarResult
- from .session import AsyncSessionTransaction
- from ...engine import Connection
- from ...engine import CursorResult
- from ...engine import Engine
- from ...engine import Result
- from ...engine import Row
- from ...engine import RowMapping
- from ...engine.interfaces import _CoreAnyExecuteParams
- from ...engine.interfaces import CoreExecuteOptionsParameter
- from ...engine.result import ScalarResult
- from ...orm._typing import _IdentityKeyType
- from ...orm._typing import _O
- from ...orm._typing import OrmExecuteOptionsParameter
- from ...orm.interfaces import ORMOption
- from ...orm.session import _BindArguments
- from ...orm.session import _EntityBindKey
- from ...orm.session import _PKIdentityArgument
- from ...orm.session import _SessionBind
- from ...sql.base import Executable
- from ...sql.dml import UpdateBase
- from ...sql.elements import ClauseElement
- from ...sql.selectable import ForUpdateParameter
- from ...sql.selectable import TypedReturnsRows
-
-_T = TypeVar("_T", bound=Any)
-
-
-@create_proxy_methods(
- AsyncSession,
- ":class:`_asyncio.AsyncSession`",
- ":class:`_asyncio.scoping.async_scoped_session`",
- classmethods=["close_all", "object_session", "identity_key"],
- methods=[
- "__contains__",
- "__iter__",
- "aclose",
- "add",
- "add_all",
- "begin",
- "begin_nested",
- "close",
- "reset",
- "commit",
- "connection",
- "delete",
- "execute",
- "expire",
- "expire_all",
- "expunge",
- "expunge_all",
- "flush",
- "get_bind",
- "is_modified",
- "invalidate",
- "merge",
- "refresh",
- "rollback",
- "scalar",
- "scalars",
- "get",
- "get_one",
- "stream",
- "stream_scalars",
- ],
- attributes=[
- "bind",
- "dirty",
- "deleted",
- "new",
- "identity_map",
- "is_active",
- "autoflush",
- "no_autoflush",
- "info",
- ],
- use_intermediate_variable=["get"],
-)
-class async_scoped_session(Generic[_AS]):
- """Provides scoped management of :class:`.AsyncSession` objects.
-
- See the section :ref:`asyncio_scoped_session` for usage details.
-
- .. versionadded:: 1.4.19
-
-
- """
-
- _support_async = True
-
- session_factory: async_sessionmaker[_AS]
- """The `session_factory` provided to `__init__` is stored in this
- attribute and may be accessed at a later time. This can be useful when
- a new non-scoped :class:`.AsyncSession` is needed."""
-
- registry: ScopedRegistry[_AS]
-
- def __init__(
- self,
- session_factory: async_sessionmaker[_AS],
- scopefunc: Callable[[], Any],
- ):
- """Construct a new :class:`_asyncio.async_scoped_session`.
-
- :param session_factory: a factory to create new :class:`_asyncio.AsyncSession`
- instances. This is usually, but not necessarily, an instance
- of :class:`_asyncio.async_sessionmaker`.
-
- :param scopefunc: function which defines
- the current scope. A function such as ``asyncio.current_task``
- may be useful here.
-
- """ # noqa: E501
-
- self.session_factory = session_factory
- self.registry = ScopedRegistry(session_factory, scopefunc)
-
- @property
- def _proxied(self) -> _AS:
- return self.registry()
-
- def __call__(self, **kw: Any) -> _AS:
- r"""Return the current :class:`.AsyncSession`, creating it
- using the :attr:`.scoped_session.session_factory` if not present.
-
- :param \**kw: Keyword arguments will be passed to the
- :attr:`.scoped_session.session_factory` callable, if an existing
- :class:`.AsyncSession` is not present. If the
- :class:`.AsyncSession` is present
- and keyword arguments have been passed,
- :exc:`~sqlalchemy.exc.InvalidRequestError` is raised.
-
- """
- if kw:
- if self.registry.has():
- raise sa_exc.InvalidRequestError(
- "Scoped session is already present; "
- "no new arguments may be specified."
- )
- else:
- sess = self.session_factory(**kw)
- self.registry.set(sess)
- else:
- sess = self.registry()
- if not self._support_async and sess._is_asyncio:
- warn_deprecated(
- "Using `scoped_session` with asyncio is deprecated and "
- "will raise an error in a future version. "
- "Please use `async_scoped_session` instead.",
- "1.4.23",
- )
- return sess
-
- def configure(self, **kwargs: Any) -> None:
- """reconfigure the :class:`.sessionmaker` used by this
- :class:`.scoped_session`.
-
- See :meth:`.sessionmaker.configure`.
-
- """
-
- if self.registry.has():
- warn(
- "At least one scoped session is already present. "
- " configure() can not affect sessions that have "
- "already been created."
- )
-
- self.session_factory.configure(**kwargs)
-
- async def remove(self) -> None:
- """Dispose of the current :class:`.AsyncSession`, if present.
-
- Different from scoped_session's remove method, this method would use
- await to wait for the close method of AsyncSession.
-
- """
-
- if self.registry.has():
- await self.registry().close()
- self.registry.clear()
-
- # START PROXY METHODS async_scoped_session
-
- # code within this block is **programmatically,
- # statically generated** by tools/generate_proxy_methods.py
-
- def __contains__(self, instance: object) -> bool:
- r"""Return True if the instance is associated with this session.
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class on
- behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
- .. container:: class_bases
-
- Proxied for the :class:`_orm.Session` class on
- behalf of the :class:`_asyncio.AsyncSession` class.
-
- The instance may be pending or persistent within the Session for a
- result of True.
-
-
-
- """ # noqa: E501
-
- return self._proxied.__contains__(instance)
-
- def __iter__(self) -> Iterator[object]:
- r"""Iterate over all pending or persistent instances within this
- Session.
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class on
- behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
- .. container:: class_bases
-
- Proxied for the :class:`_orm.Session` class on
- behalf of the :class:`_asyncio.AsyncSession` class.
-
-
-
- """ # noqa: E501
-
- return self._proxied.__iter__()
-
- async def aclose(self) -> None:
- r"""A synonym for :meth:`_asyncio.AsyncSession.close`.
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class on
- behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
- The :meth:`_asyncio.AsyncSession.aclose` name is specifically
- to support the Python standard library ``@contextlib.aclosing``
- context manager function.
-
- .. versionadded:: 2.0.20
-
-
- """ # noqa: E501
-
- return await self._proxied.aclose()
-
- def add(self, instance: object, _warn: bool = True) -> None:
- r"""Place an object into this :class:`_orm.Session`.
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class on
- behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
- .. container:: class_bases
-
- Proxied for the :class:`_orm.Session` class on
- behalf of the :class:`_asyncio.AsyncSession` class.
-
- Objects that are in the :term:`transient` state when passed to the
- :meth:`_orm.Session.add` method will move to the
- :term:`pending` state, until the next flush, at which point they
- will move to the :term:`persistent` state.
-
- Objects that are in the :term:`detached` state when passed to the
- :meth:`_orm.Session.add` method will move to the :term:`persistent`
- state directly.
-
- If the transaction used by the :class:`_orm.Session` is rolled back,
- objects which were transient when they were passed to
- :meth:`_orm.Session.add` will be moved back to the
- :term:`transient` state, and will no longer be present within this
- :class:`_orm.Session`.
-
- .. seealso::
-
- :meth:`_orm.Session.add_all`
-
- :ref:`session_adding` - at :ref:`session_basics`
-
-
-
- """ # noqa: E501
-
- return self._proxied.add(instance, _warn=_warn)
-
- def add_all(self, instances: Iterable[object]) -> None:
- r"""Add the given collection of instances to this :class:`_orm.Session`.
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class on
- behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
- .. container:: class_bases
-
- Proxied for the :class:`_orm.Session` class on
- behalf of the :class:`_asyncio.AsyncSession` class.
-
- See the documentation for :meth:`_orm.Session.add` for a general
- behavioral description.
-
- .. seealso::
-
- :meth:`_orm.Session.add`
-
- :ref:`session_adding` - at :ref:`session_basics`
-
-
-
- """ # noqa: E501
-
- return self._proxied.add_all(instances)
-
- def begin(self) -> AsyncSessionTransaction:
- r"""Return an :class:`_asyncio.AsyncSessionTransaction` object.
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class on
- behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
- The underlying :class:`_orm.Session` will perform the
- "begin" action when the :class:`_asyncio.AsyncSessionTransaction`
- object is entered::
-
- async with async_session.begin():
- # .. ORM transaction is begun
-
- Note that database IO will not normally occur when the session-level
- transaction is begun, as database transactions begin on an
- on-demand basis. However, the begin block is async to accommodate
- for a :meth:`_orm.SessionEvents.after_transaction_create`
- event hook that may perform IO.
-
- For a general description of ORM begin, see
- :meth:`_orm.Session.begin`.
-
-
- """ # noqa: E501
-
- return self._proxied.begin()
-
- def begin_nested(self) -> AsyncSessionTransaction:
- r"""Return an :class:`_asyncio.AsyncSessionTransaction` object
- which will begin a "nested" transaction, e.g. SAVEPOINT.
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class on
- behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
- Behavior is the same as that of :meth:`_asyncio.AsyncSession.begin`.
-
- For a general description of ORM begin nested, see
- :meth:`_orm.Session.begin_nested`.
-
- .. seealso::
-
- :ref:`aiosqlite_serializable` - special workarounds required
- with the SQLite asyncio driver in order for SAVEPOINT to work
- correctly.
-
-
- """ # noqa: E501
-
- return self._proxied.begin_nested()
-
- async def close(self) -> None:
- r"""Close out the transactional resources and ORM objects used by this
- :class:`_asyncio.AsyncSession`.
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class on
- behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
- .. seealso::
-
- :meth:`_orm.Session.close` - main documentation for
- "close"
-
- :ref:`session_closing` - detail on the semantics of
- :meth:`_asyncio.AsyncSession.close` and
- :meth:`_asyncio.AsyncSession.reset`.
-
-
- """ # noqa: E501
-
- return await self._proxied.close()
-
- async def reset(self) -> None:
- r"""Close out the transactional resources and ORM objects used by this
- :class:`_orm.Session`, resetting the session to its initial state.
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class on
- behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
- .. versionadded:: 2.0.22
-
- .. seealso::
-
- :meth:`_orm.Session.reset` - main documentation for
- "reset"
-
- :ref:`session_closing` - detail on the semantics of
- :meth:`_asyncio.AsyncSession.close` and
- :meth:`_asyncio.AsyncSession.reset`.
-
-
- """ # noqa: E501
-
- return await self._proxied.reset()
-
- async def commit(self) -> None:
- r"""Commit the current transaction in progress.
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class on
- behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
- .. seealso::
-
- :meth:`_orm.Session.commit` - main documentation for
- "commit"
-
- """ # noqa: E501
-
- return await self._proxied.commit()
-
- async def connection(
- self,
- bind_arguments: Optional[_BindArguments] = None,
- execution_options: Optional[CoreExecuteOptionsParameter] = None,
- **kw: Any,
- ) -> AsyncConnection:
- r"""Return a :class:`_asyncio.AsyncConnection` object corresponding to
- this :class:`.Session` object's transactional state.
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class on
- behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
- This method may also be used to establish execution options for the
- database connection used by the current transaction.
-
- .. versionadded:: 1.4.24 Added \**kw arguments which are passed
- through to the underlying :meth:`_orm.Session.connection` method.
-
- .. seealso::
-
- :meth:`_orm.Session.connection` - main documentation for
- "connection"
-
-
- """ # noqa: E501
-
- return await self._proxied.connection(
- bind_arguments=bind_arguments,
- execution_options=execution_options,
- **kw,
- )
-
- async def delete(self, instance: object) -> None:
- r"""Mark an instance as deleted.
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class on
- behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
- The database delete operation occurs upon ``flush()``.
-
- As this operation may need to cascade along unloaded relationships,
- it is awaitable to allow for those queries to take place.
-
- .. seealso::
-
- :meth:`_orm.Session.delete` - main documentation for delete
-
-
- """ # noqa: E501
-
- return await self._proxied.delete(instance)
-
- @overload
- async def execute(
- self,
- statement: TypedReturnsRows[_T],
- params: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
- bind_arguments: Optional[_BindArguments] = None,
- _parent_execute_state: Optional[Any] = None,
- _add_event: Optional[Any] = None,
- ) -> Result[_T]: ...
-
- @overload
- async def execute(
- self,
- statement: UpdateBase,
- params: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
- bind_arguments: Optional[_BindArguments] = None,
- _parent_execute_state: Optional[Any] = None,
- _add_event: Optional[Any] = None,
- ) -> CursorResult[Any]: ...
-
- @overload
- async def execute(
- self,
- statement: Executable,
- params: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
- bind_arguments: Optional[_BindArguments] = None,
- _parent_execute_state: Optional[Any] = None,
- _add_event: Optional[Any] = None,
- ) -> Result[Any]: ...
-
- async def execute(
- self,
- statement: Executable,
- params: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
- bind_arguments: Optional[_BindArguments] = None,
- **kw: Any,
- ) -> Result[Any]:
- r"""Execute a statement and return a buffered
- :class:`_engine.Result` object.
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class on
- behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
- .. seealso::
-
- :meth:`_orm.Session.execute` - main documentation for execute
-
-
- """ # noqa: E501
-
- return await self._proxied.execute(
- statement,
- params=params,
- execution_options=execution_options,
- bind_arguments=bind_arguments,
- **kw,
- )
-
- def expire(
- self, instance: object, attribute_names: Optional[Iterable[str]] = None
- ) -> None:
- r"""Expire the attributes on an instance.
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class on
- behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
- .. container:: class_bases
-
- Proxied for the :class:`_orm.Session` class on
- behalf of the :class:`_asyncio.AsyncSession` class.
-
- Marks the attributes of an instance as out of date. When an expired
- attribute is next accessed, a query will be issued to the
- :class:`.Session` object's current transactional context in order to
- load all expired attributes for the given instance. Note that
- a highly isolated transaction will return the same values as were
- previously read in that same transaction, regardless of changes
- in database state outside of that transaction.
-
- To expire all objects in the :class:`.Session` simultaneously,
- use :meth:`Session.expire_all`.
-
- The :class:`.Session` object's default behavior is to
- expire all state whenever the :meth:`Session.rollback`
- or :meth:`Session.commit` methods are called, so that new
- state can be loaded for the new transaction. For this reason,
- calling :meth:`Session.expire` only makes sense for the specific
- case that a non-ORM SQL statement was emitted in the current
- transaction.
-
- :param instance: The instance to be refreshed.
- :param attribute_names: optional list of string attribute names
- indicating a subset of attributes to be expired.
-
- .. seealso::
-
- :ref:`session_expire` - introductory material
-
- :meth:`.Session.expire`
-
- :meth:`.Session.refresh`
-
- :meth:`_orm.Query.populate_existing`
-
-
-
- """ # noqa: E501
-
- return self._proxied.expire(instance, attribute_names=attribute_names)
-
- def expire_all(self) -> None:
- r"""Expires all persistent instances within this Session.
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class on
- behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
- .. container:: class_bases
-
- Proxied for the :class:`_orm.Session` class on
- behalf of the :class:`_asyncio.AsyncSession` class.
-
- When any attributes on a persistent instance is next accessed,
- a query will be issued using the
- :class:`.Session` object's current transactional context in order to
- load all expired attributes for the given instance. Note that
- a highly isolated transaction will return the same values as were
- previously read in that same transaction, regardless of changes
- in database state outside of that transaction.
-
- To expire individual objects and individual attributes
- on those objects, use :meth:`Session.expire`.
-
- The :class:`.Session` object's default behavior is to
- expire all state whenever the :meth:`Session.rollback`
- or :meth:`Session.commit` methods are called, so that new
- state can be loaded for the new transaction. For this reason,
- calling :meth:`Session.expire_all` is not usually needed,
- assuming the transaction is isolated.
-
- .. seealso::
-
- :ref:`session_expire` - introductory material
-
- :meth:`.Session.expire`
-
- :meth:`.Session.refresh`
-
- :meth:`_orm.Query.populate_existing`
-
-
-
- """ # noqa: E501
-
- return self._proxied.expire_all()
-
- def expunge(self, instance: object) -> None:
- r"""Remove the `instance` from this ``Session``.
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class on
- behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
- .. container:: class_bases
-
- Proxied for the :class:`_orm.Session` class on
- behalf of the :class:`_asyncio.AsyncSession` class.
-
- This will free all internal references to the instance. Cascading
- will be applied according to the *expunge* cascade rule.
-
-
-
- """ # noqa: E501
-
- return self._proxied.expunge(instance)
-
- def expunge_all(self) -> None:
- r"""Remove all object instances from this ``Session``.
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class on
- behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
- .. container:: class_bases
-
- Proxied for the :class:`_orm.Session` class on
- behalf of the :class:`_asyncio.AsyncSession` class.
-
- This is equivalent to calling ``expunge(obj)`` on all objects in this
- ``Session``.
-
-
-
- """ # noqa: E501
-
- return self._proxied.expunge_all()
-
- async def flush(self, objects: Optional[Sequence[Any]] = None) -> None:
- r"""Flush all the object changes to the database.
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class on
- behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
- .. seealso::
-
- :meth:`_orm.Session.flush` - main documentation for flush
-
-
- """ # noqa: E501
-
- return await self._proxied.flush(objects=objects)
-
- def get_bind(
- self,
- mapper: Optional[_EntityBindKey[_O]] = None,
- clause: Optional[ClauseElement] = None,
- bind: Optional[_SessionBind] = None,
- **kw: Any,
- ) -> Union[Engine, Connection]:
- r"""Return a "bind" to which the synchronous proxied :class:`_orm.Session`
- is bound.
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class on
- behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
- Unlike the :meth:`_orm.Session.get_bind` method, this method is
- currently **not** used by this :class:`.AsyncSession` in any way
- in order to resolve engines for requests.
-
- .. note::
-
- This method proxies directly to the :meth:`_orm.Session.get_bind`
- method, however is currently **not** useful as an override target,
- in contrast to that of the :meth:`_orm.Session.get_bind` method.
- The example below illustrates how to implement custom
- :meth:`_orm.Session.get_bind` schemes that work with
- :class:`.AsyncSession` and :class:`.AsyncEngine`.
-
- The pattern introduced at :ref:`session_custom_partitioning`
- illustrates how to apply a custom bind-lookup scheme to a
- :class:`_orm.Session` given a set of :class:`_engine.Engine` objects.
- To apply a corresponding :meth:`_orm.Session.get_bind` implementation
- for use with a :class:`.AsyncSession` and :class:`.AsyncEngine`
- objects, continue to subclass :class:`_orm.Session` and apply it to
- :class:`.AsyncSession` using
- :paramref:`.AsyncSession.sync_session_class`. The inner method must
- continue to return :class:`_engine.Engine` instances, which can be
- acquired from a :class:`_asyncio.AsyncEngine` using the
- :attr:`_asyncio.AsyncEngine.sync_engine` attribute::
-
- # using example from "Custom Vertical Partitioning"
-
-
- import random
-
- from sqlalchemy.ext.asyncio import AsyncSession
- from sqlalchemy.ext.asyncio import create_async_engine
- from sqlalchemy.ext.asyncio import async_sessionmaker
- from sqlalchemy.orm import Session
-
- # construct async engines w/ async drivers
- engines = {
- 'leader':create_async_engine("sqlite+aiosqlite:///leader.db"),
- 'other':create_async_engine("sqlite+aiosqlite:///other.db"),
- 'follower1':create_async_engine("sqlite+aiosqlite:///follower1.db"),
- 'follower2':create_async_engine("sqlite+aiosqlite:///follower2.db"),
- }
-
- class RoutingSession(Session):
- def get_bind(self, mapper=None, clause=None, **kw):
- # within get_bind(), return sync engines
- if mapper and issubclass(mapper.class_, MyOtherClass):
- return engines['other'].sync_engine
- elif self._flushing or isinstance(clause, (Update, Delete)):
- return engines['leader'].sync_engine
- else:
- return engines[
- random.choice(['follower1','follower2'])
- ].sync_engine
-
- # apply to AsyncSession using sync_session_class
- AsyncSessionMaker = async_sessionmaker(
- sync_session_class=RoutingSession
- )
-
- The :meth:`_orm.Session.get_bind` method is called in a non-asyncio,
- implicitly non-blocking context in the same manner as ORM event hooks
- and functions that are invoked via :meth:`.AsyncSession.run_sync`, so
- routines that wish to run SQL commands inside of
- :meth:`_orm.Session.get_bind` can continue to do so using
- blocking-style code, which will be translated to implicitly async calls
- at the point of invoking IO on the database drivers.
-
-
- """ # noqa: E501
-
- return self._proxied.get_bind(
- mapper=mapper, clause=clause, bind=bind, **kw
- )
-
- def is_modified(
- self, instance: object, include_collections: bool = True
- ) -> bool:
- r"""Return ``True`` if the given instance has locally
- modified attributes.
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class on
- behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
- .. container:: class_bases
-
- Proxied for the :class:`_orm.Session` class on
- behalf of the :class:`_asyncio.AsyncSession` class.
-
- This method retrieves the history for each instrumented
- attribute on the instance and performs a comparison of the current
- value to its previously committed value, if any.
-
- It is in effect a more expensive and accurate
- version of checking for the given instance in the
- :attr:`.Session.dirty` collection; a full test for
- each attribute's net "dirty" status is performed.
-
- E.g.::
-
- return session.is_modified(someobject)
-
- A few caveats to this method apply:
-
- * Instances present in the :attr:`.Session.dirty` collection may
- report ``False`` when tested with this method. This is because
- the object may have received change events via attribute mutation,
- thus placing it in :attr:`.Session.dirty`, but ultimately the state
- is the same as that loaded from the database, resulting in no net
- change here.
- * Scalar attributes may not have recorded the previously set
- value when a new value was applied, if the attribute was not loaded,
- or was expired, at the time the new value was received - in these
- cases, the attribute is assumed to have a change, even if there is
- ultimately no net change against its database value. SQLAlchemy in
- most cases does not need the "old" value when a set event occurs, so
- it skips the expense of a SQL call if the old value isn't present,
- based on the assumption that an UPDATE of the scalar value is
- usually needed, and in those few cases where it isn't, is less
- expensive on average than issuing a defensive SELECT.
-
- The "old" value is fetched unconditionally upon set only if the
- attribute container has the ``active_history`` flag set to ``True``.
- This flag is set typically for primary key attributes and scalar
- object references that are not a simple many-to-one. To set this
- flag for any arbitrary mapped column, use the ``active_history``
- argument with :func:`.column_property`.
-
- :param instance: mapped instance to be tested for pending changes.
- :param include_collections: Indicates if multivalued collections
- should be included in the operation. Setting this to ``False`` is a
- way to detect only local-column based properties (i.e. scalar columns
- or many-to-one foreign keys) that would result in an UPDATE for this
- instance upon flush.
-
-
-
- """ # noqa: E501
-
- return self._proxied.is_modified(
- instance, include_collections=include_collections
- )
-
- async def invalidate(self) -> None:
- r"""Close this Session, using connection invalidation.
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class on
- behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
- For a complete description, see :meth:`_orm.Session.invalidate`.
-
- """ # noqa: E501
-
- return await self._proxied.invalidate()
-
- async def merge(
- self,
- instance: _O,
- *,
- load: bool = True,
- options: Optional[Sequence[ORMOption]] = None,
- ) -> _O:
- r"""Copy the state of a given instance into a corresponding instance
- within this :class:`_asyncio.AsyncSession`.
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class on
- behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
- .. seealso::
-
- :meth:`_orm.Session.merge` - main documentation for merge
-
-
- """ # noqa: E501
-
- return await self._proxied.merge(instance, load=load, options=options)
-
- async def refresh(
- self,
- instance: object,
- attribute_names: Optional[Iterable[str]] = None,
- with_for_update: ForUpdateParameter = None,
- ) -> None:
- r"""Expire and refresh the attributes on the given instance.
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class on
- behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
- A query will be issued to the database and all attributes will be
- refreshed with their current database value.
-
- This is the async version of the :meth:`_orm.Session.refresh` method.
- See that method for a complete description of all options.
-
- .. seealso::
-
- :meth:`_orm.Session.refresh` - main documentation for refresh
-
-
- """ # noqa: E501
-
- return await self._proxied.refresh(
- instance,
- attribute_names=attribute_names,
- with_for_update=with_for_update,
- )
-
- async def rollback(self) -> None:
- r"""Rollback the current transaction in progress.
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class on
- behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
- .. seealso::
-
- :meth:`_orm.Session.rollback` - main documentation for
- "rollback"
-
- """ # noqa: E501
-
- return await self._proxied.rollback()
-
- @overload
- async def scalar(
- self,
- statement: TypedReturnsRows[Tuple[_T]],
- params: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
- bind_arguments: Optional[_BindArguments] = None,
- **kw: Any,
- ) -> Optional[_T]: ...
-
- @overload
- async def scalar(
- self,
- statement: Executable,
- params: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
- bind_arguments: Optional[_BindArguments] = None,
- **kw: Any,
- ) -> Any: ...
-
- async def scalar(
- self,
- statement: Executable,
- params: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
- bind_arguments: Optional[_BindArguments] = None,
- **kw: Any,
- ) -> Any:
- r"""Execute a statement and return a scalar result.
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class on
- behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
- .. seealso::
-
- :meth:`_orm.Session.scalar` - main documentation for scalar
-
-
- """ # noqa: E501
-
- return await self._proxied.scalar(
- statement,
- params=params,
- execution_options=execution_options,
- bind_arguments=bind_arguments,
- **kw,
- )
-
- @overload
- async def scalars(
- self,
- statement: TypedReturnsRows[Tuple[_T]],
- params: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
- bind_arguments: Optional[_BindArguments] = None,
- **kw: Any,
- ) -> ScalarResult[_T]: ...
-
- @overload
- async def scalars(
- self,
- statement: Executable,
- params: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
- bind_arguments: Optional[_BindArguments] = None,
- **kw: Any,
- ) -> ScalarResult[Any]: ...
-
- async def scalars(
- self,
- statement: Executable,
- params: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
- bind_arguments: Optional[_BindArguments] = None,
- **kw: Any,
- ) -> ScalarResult[Any]:
- r"""Execute a statement and return scalar results.
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class on
- behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
- :return: a :class:`_result.ScalarResult` object
-
- .. versionadded:: 1.4.24 Added :meth:`_asyncio.AsyncSession.scalars`
-
- .. versionadded:: 1.4.26 Added
- :meth:`_asyncio.async_scoped_session.scalars`
-
- .. seealso::
-
- :meth:`_orm.Session.scalars` - main documentation for scalars
-
- :meth:`_asyncio.AsyncSession.stream_scalars` - streaming version
-
-
- """ # noqa: E501
-
- return await self._proxied.scalars(
- statement,
- params=params,
- execution_options=execution_options,
- bind_arguments=bind_arguments,
- **kw,
- )
-
- async def get(
- self,
- entity: _EntityBindKey[_O],
- ident: _PKIdentityArgument,
- *,
- options: Optional[Sequence[ORMOption]] = None,
- populate_existing: bool = False,
- with_for_update: ForUpdateParameter = None,
- identity_token: Optional[Any] = None,
- execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
- ) -> Union[_O, None]:
- r"""Return an instance based on the given primary key identifier,
- or ``None`` if not found.
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class on
- behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
- .. seealso::
-
- :meth:`_orm.Session.get` - main documentation for get
-
-
-
- """ # noqa: E501
-
- result = await self._proxied.get(
- entity,
- ident,
- options=options,
- populate_existing=populate_existing,
- with_for_update=with_for_update,
- identity_token=identity_token,
- execution_options=execution_options,
- )
- return result
-
- async def get_one(
- self,
- entity: _EntityBindKey[_O],
- ident: _PKIdentityArgument,
- *,
- options: Optional[Sequence[ORMOption]] = None,
- populate_existing: bool = False,
- with_for_update: ForUpdateParameter = None,
- identity_token: Optional[Any] = None,
- execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
- ) -> _O:
- r"""Return an instance based on the given primary key identifier,
- or raise an exception if not found.
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class on
- behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
- Raises ``sqlalchemy.orm.exc.NoResultFound`` if the query selects
- no rows.
-
- ..versionadded: 2.0.22
-
- .. seealso::
-
- :meth:`_orm.Session.get_one` - main documentation for get_one
-
-
- """ # noqa: E501
-
- return await self._proxied.get_one(
- entity,
- ident,
- options=options,
- populate_existing=populate_existing,
- with_for_update=with_for_update,
- identity_token=identity_token,
- execution_options=execution_options,
- )
-
- @overload
- async def stream(
- self,
- statement: TypedReturnsRows[_T],
- params: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
- bind_arguments: Optional[_BindArguments] = None,
- **kw: Any,
- ) -> AsyncResult[_T]: ...
-
- @overload
- async def stream(
- self,
- statement: Executable,
- params: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
- bind_arguments: Optional[_BindArguments] = None,
- **kw: Any,
- ) -> AsyncResult[Any]: ...
-
- async def stream(
- self,
- statement: Executable,
- params: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
- bind_arguments: Optional[_BindArguments] = None,
- **kw: Any,
- ) -> AsyncResult[Any]:
- r"""Execute a statement and return a streaming
- :class:`_asyncio.AsyncResult` object.
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class on
- behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
-
- """ # noqa: E501
-
- return await self._proxied.stream(
- statement,
- params=params,
- execution_options=execution_options,
- bind_arguments=bind_arguments,
- **kw,
- )
-
- @overload
- async def stream_scalars(
- self,
- statement: TypedReturnsRows[Tuple[_T]],
- params: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
- bind_arguments: Optional[_BindArguments] = None,
- **kw: Any,
- ) -> AsyncScalarResult[_T]: ...
-
- @overload
- async def stream_scalars(
- self,
- statement: Executable,
- params: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
- bind_arguments: Optional[_BindArguments] = None,
- **kw: Any,
- ) -> AsyncScalarResult[Any]: ...
-
- async def stream_scalars(
- self,
- statement: Executable,
- params: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
- bind_arguments: Optional[_BindArguments] = None,
- **kw: Any,
- ) -> AsyncScalarResult[Any]:
- r"""Execute a statement and return a stream of scalar results.
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class on
- behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
- :return: an :class:`_asyncio.AsyncScalarResult` object
-
- .. versionadded:: 1.4.24
-
- .. seealso::
-
- :meth:`_orm.Session.scalars` - main documentation for scalars
-
- :meth:`_asyncio.AsyncSession.scalars` - non streaming version
-
-
- """ # noqa: E501
-
- return await self._proxied.stream_scalars(
- statement,
- params=params,
- execution_options=execution_options,
- bind_arguments=bind_arguments,
- **kw,
- )
-
- @property
- def bind(self) -> Any:
- r"""Proxy for the :attr:`_asyncio.AsyncSession.bind` attribute
- on behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
- """ # noqa: E501
-
- return self._proxied.bind
-
- @bind.setter
- def bind(self, attr: Any) -> None:
- self._proxied.bind = attr
-
- @property
- def dirty(self) -> Any:
- r"""The set of all persistent instances considered dirty.
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class
- on behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
- .. container:: class_bases
-
- Proxied for the :class:`_orm.Session` class
- on behalf of the :class:`_asyncio.AsyncSession` class.
-
- E.g.::
-
- some_mapped_object in session.dirty
-
- Instances are considered dirty when they were modified but not
- deleted.
-
- Note that this 'dirty' calculation is 'optimistic'; most
- attribute-setting or collection modification operations will
- mark an instance as 'dirty' and place it in this set, even if
- there is no net change to the attribute's value. At flush
- time, the value of each attribute is compared to its
- previously saved value, and if there's no net change, no SQL
- operation will occur (this is a more expensive operation so
- it's only done at flush time).
-
- To check if an instance has actionable net changes to its
- attributes, use the :meth:`.Session.is_modified` method.
-
-
-
- """ # noqa: E501
-
- return self._proxied.dirty
-
- @property
- def deleted(self) -> Any:
- r"""The set of all instances marked as 'deleted' within this ``Session``
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class
- on behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
- .. container:: class_bases
-
- Proxied for the :class:`_orm.Session` class
- on behalf of the :class:`_asyncio.AsyncSession` class.
-
-
- """ # noqa: E501
-
- return self._proxied.deleted
-
- @property
- def new(self) -> Any:
- r"""The set of all instances marked as 'new' within this ``Session``.
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class
- on behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
- .. container:: class_bases
-
- Proxied for the :class:`_orm.Session` class
- on behalf of the :class:`_asyncio.AsyncSession` class.
-
-
- """ # noqa: E501
-
- return self._proxied.new
-
- @property
- def identity_map(self) -> Any:
- r"""Proxy for the :attr:`_orm.Session.identity_map` attribute
- on behalf of the :class:`_asyncio.AsyncSession` class.
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class
- on behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
-
- """ # noqa: E501
-
- return self._proxied.identity_map
-
- @identity_map.setter
- def identity_map(self, attr: Any) -> None:
- self._proxied.identity_map = attr
-
- @property
- def is_active(self) -> Any:
- r"""True if this :class:`.Session` not in "partial rollback" state.
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class
- on behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
- .. container:: class_bases
-
- Proxied for the :class:`_orm.Session` class
- on behalf of the :class:`_asyncio.AsyncSession` class.
-
- .. versionchanged:: 1.4 The :class:`_orm.Session` no longer begins
- a new transaction immediately, so this attribute will be False
- when the :class:`_orm.Session` is first instantiated.
-
- "partial rollback" state typically indicates that the flush process
- of the :class:`_orm.Session` has failed, and that the
- :meth:`_orm.Session.rollback` method must be emitted in order to
- fully roll back the transaction.
-
- If this :class:`_orm.Session` is not in a transaction at all, the
- :class:`_orm.Session` will autobegin when it is first used, so in this
- case :attr:`_orm.Session.is_active` will return True.
-
- Otherwise, if this :class:`_orm.Session` is within a transaction,
- and that transaction has not been rolled back internally, the
- :attr:`_orm.Session.is_active` will also return True.
-
- .. seealso::
-
- :ref:`faq_session_rollback`
-
- :meth:`_orm.Session.in_transaction`
-
-
-
- """ # noqa: E501
-
- return self._proxied.is_active
-
- @property
- def autoflush(self) -> Any:
- r"""Proxy for the :attr:`_orm.Session.autoflush` attribute
- on behalf of the :class:`_asyncio.AsyncSession` class.
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class
- on behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
-
- """ # noqa: E501
-
- return self._proxied.autoflush
-
- @autoflush.setter
- def autoflush(self, attr: Any) -> None:
- self._proxied.autoflush = attr
-
- @property
- def no_autoflush(self) -> Any:
- r"""Return a context manager that disables autoflush.
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class
- on behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
- .. container:: class_bases
-
- Proxied for the :class:`_orm.Session` class
- on behalf of the :class:`_asyncio.AsyncSession` class.
-
- e.g.::
-
- with session.no_autoflush:
-
- some_object = SomeClass()
- session.add(some_object)
- # won't autoflush
- some_object.related_thing = session.query(SomeRelated).first()
-
- Operations that proceed within the ``with:`` block
- will not be subject to flushes occurring upon query
- access. This is useful when initializing a series
- of objects which involve existing database queries,
- where the uncompleted object should not yet be flushed.
-
-
-
- """ # noqa: E501
-
- return self._proxied.no_autoflush
-
- @property
- def info(self) -> Any:
- r"""A user-modifiable dictionary.
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class
- on behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
- .. container:: class_bases
-
- Proxied for the :class:`_orm.Session` class
- on behalf of the :class:`_asyncio.AsyncSession` class.
-
- The initial value of this dictionary can be populated using the
- ``info`` argument to the :class:`.Session` constructor or
- :class:`.sessionmaker` constructor or factory methods. The dictionary
- here is always local to this :class:`.Session` and can be modified
- independently of all other :class:`.Session` objects.
-
-
-
- """ # noqa: E501
-
- return self._proxied.info
-
- @classmethod
- async def close_all(cls) -> None:
- r"""Close all :class:`_asyncio.AsyncSession` sessions.
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class on
- behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
- .. deprecated:: 2.0 The :meth:`.AsyncSession.close_all` method is deprecated and will be removed in a future release. Please refer to :func:`_asyncio.close_all_sessions`.
-
- """ # noqa: E501
-
- return await AsyncSession.close_all()
-
- @classmethod
- def object_session(cls, instance: object) -> Optional[Session]:
- r"""Return the :class:`.Session` to which an object belongs.
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class on
- behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
- .. container:: class_bases
-
- Proxied for the :class:`_orm.Session` class on
- behalf of the :class:`_asyncio.AsyncSession` class.
-
- This is an alias of :func:`.object_session`.
-
-
-
- """ # noqa: E501
-
- return AsyncSession.object_session(instance)
-
- @classmethod
- def identity_key(
- cls,
- class_: Optional[Type[Any]] = None,
- ident: Union[Any, Tuple[Any, ...]] = None,
- *,
- instance: Optional[Any] = None,
- row: Optional[Union[Row[Any], RowMapping]] = None,
- identity_token: Optional[Any] = None,
- ) -> _IdentityKeyType[Any]:
- r"""Return an identity key.
-
- .. container:: class_bases
-
- Proxied for the :class:`_asyncio.AsyncSession` class on
- behalf of the :class:`_asyncio.scoping.async_scoped_session` class.
-
- .. container:: class_bases
-
- Proxied for the :class:`_orm.Session` class on
- behalf of the :class:`_asyncio.AsyncSession` class.
-
- This is an alias of :func:`.util.identity_key`.
-
-
-
- """ # noqa: E501
-
- return AsyncSession.identity_key(
- class_=class_,
- ident=ident,
- instance=instance,
- row=row,
- identity_token=identity_token,
- )
-
- # END PROXY METHODS async_scoped_session
diff --git a/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/session.py b/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/session.py
deleted file mode 100644
index c5fe469..0000000
--- a/venv/lib/python3.11/site-packages/sqlalchemy/ext/asyncio/session.py
+++ /dev/null
@@ -1,1936 +0,0 @@
-# ext/asyncio/session.py
-# Copyright (C) 2020-2024 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
-from __future__ import annotations
-
-import asyncio
-from typing import Any
-from typing import Awaitable
-from typing import Callable
-from typing import cast
-from typing import Dict
-from typing import Generic
-from typing import Iterable
-from typing import Iterator
-from typing import NoReturn
-from typing import Optional
-from typing import overload
-from typing import Sequence
-from typing import Tuple
-from typing import Type
-from typing import TYPE_CHECKING
-from typing import TypeVar
-from typing import Union
-
-from . import engine
-from .base import ReversibleProxy
-from .base import StartableContext
-from .result import _ensure_sync_result
-from .result import AsyncResult
-from .result import AsyncScalarResult
-from ... import util
-from ...orm import close_all_sessions as _sync_close_all_sessions
-from ...orm import object_session
-from ...orm import Session
-from ...orm import SessionTransaction
-from ...orm import state as _instance_state
-from ...util.concurrency import greenlet_spawn
-from ...util.typing import Concatenate
-from ...util.typing import ParamSpec
-
-
-if TYPE_CHECKING:
- from .engine import AsyncConnection
- from .engine import AsyncEngine
- from ...engine import Connection
- from ...engine import CursorResult
- from ...engine import Engine
- from ...engine import Result
- from ...engine import Row
- from ...engine import RowMapping
- from ...engine import ScalarResult
- from ...engine.interfaces import _CoreAnyExecuteParams
- from ...engine.interfaces import CoreExecuteOptionsParameter
- from ...event import dispatcher
- from ...orm._typing import _IdentityKeyType
- from ...orm._typing import _O
- from ...orm._typing import OrmExecuteOptionsParameter
- from ...orm.identity import IdentityMap
- from ...orm.interfaces import ORMOption
- from ...orm.session import _BindArguments
- from ...orm.session import _EntityBindKey
- from ...orm.session import _PKIdentityArgument
- from ...orm.session import _SessionBind
- from ...orm.session import _SessionBindKey
- from ...sql._typing import _InfoType
- from ...sql.base import Executable
- from ...sql.dml import UpdateBase
- from ...sql.elements import ClauseElement
- from ...sql.selectable import ForUpdateParameter
- from ...sql.selectable import TypedReturnsRows
-
-_AsyncSessionBind = Union["AsyncEngine", "AsyncConnection"]
-
-_P = ParamSpec("_P")
-_T = TypeVar("_T", bound=Any)
-
-
-_EXECUTE_OPTIONS = util.immutabledict({"prebuffer_rows": True})
-_STREAM_OPTIONS = util.immutabledict({"stream_results": True})
-
-
-class AsyncAttrs:
- """Mixin class which provides an awaitable accessor for all attributes.
-
- E.g.::
-
- from __future__ import annotations
-
- from typing import List
-
- from sqlalchemy import ForeignKey
- from sqlalchemy import func
- from sqlalchemy.ext.asyncio import AsyncAttrs
- from sqlalchemy.orm import DeclarativeBase
- from sqlalchemy.orm import Mapped
- from sqlalchemy.orm import mapped_column
- from sqlalchemy.orm import relationship
-
-
- class Base(AsyncAttrs, DeclarativeBase):
- pass
-
-
- class A(Base):
- __tablename__ = "a"
-
- id: Mapped[int] = mapped_column(primary_key=True)
- data: Mapped[str]
- bs: Mapped[List[B]] = relationship()
-
-
- class B(Base):
- __tablename__ = "b"
- id: Mapped[int] = mapped_column(primary_key=True)
- a_id: Mapped[int] = mapped_column(ForeignKey("a.id"))
- data: Mapped[str]
-
- In the above example, the :class:`_asyncio.AsyncAttrs` mixin is applied to
- the declarative ``Base`` class where it takes effect for all subclasses.
- This mixin adds a single new attribute
- :attr:`_asyncio.AsyncAttrs.awaitable_attrs` to all classes, which will
- yield the value of any attribute as an awaitable. This allows attributes
- which may be subject to lazy loading or deferred / unexpiry loading to be
- accessed such that IO can still be emitted::
-
- a1 = (await async_session.scalars(select(A).where(A.id == 5))).one()
-
- # use the lazy loader on ``a1.bs`` via the ``.awaitable_attrs``
- # interface, so that it may be awaited
- for b1 in await a1.awaitable_attrs.bs:
- print(b1)
-
- The :attr:`_asyncio.AsyncAttrs.awaitable_attrs` performs a call against the
- attribute that is approximately equivalent to using the
- :meth:`_asyncio.AsyncSession.run_sync` method, e.g.::
-
- for b1 in await async_session.run_sync(lambda sess: a1.bs):
- print(b1)
-
- .. versionadded:: 2.0.13
-
- .. seealso::
-
- :ref:`asyncio_orm_avoid_lazyloads`
-
- """
-
- class _AsyncAttrGetitem:
- __slots__ = "_instance"
-
- def __init__(self, _instance: Any):
- self._instance = _instance
-
- def __getattr__(self, name: str) -> Awaitable[Any]:
- return greenlet_spawn(getattr, self._instance, name)
-
- @property
- def awaitable_attrs(self) -> AsyncAttrs._AsyncAttrGetitem:
- """provide a namespace of all attributes on this object wrapped
- as awaitables.
-
- e.g.::
-
-
- a1 = (await async_session.scalars(select(A).where(A.id == 5))).one()
-
- some_attribute = await a1.awaitable_attrs.some_deferred_attribute
- some_collection = await a1.awaitable_attrs.some_collection
-
- """ # noqa: E501
-
- return AsyncAttrs._AsyncAttrGetitem(self)
-
-
-@util.create_proxy_methods(
- Session,
- ":class:`_orm.Session`",
- ":class:`_asyncio.AsyncSession`",
- classmethods=["object_session", "identity_key"],
- methods=[
- "__contains__",
- "__iter__",
- "add",
- "add_all",
- "expire",
- "expire_all",
- "expunge",
- "expunge_all",
- "is_modified",
- "in_transaction",
- "in_nested_transaction",
- ],
- attributes=[
- "dirty",
- "deleted",
- "new",
- "identity_map",
- "is_active",
- "autoflush",
- "no_autoflush",
- "info",
- ],
-)
-class AsyncSession(ReversibleProxy[Session]):
- """Asyncio version of :class:`_orm.Session`.
-
- The :class:`_asyncio.AsyncSession` is a proxy for a traditional
- :class:`_orm.Session` instance.
-
- The :class:`_asyncio.AsyncSession` is **not safe for use in concurrent
- tasks.**. See :ref:`session_faq_threadsafe` for background.
-
- .. versionadded:: 1.4
-
- To use an :class:`_asyncio.AsyncSession` with custom :class:`_orm.Session`
- implementations, see the
- :paramref:`_asyncio.AsyncSession.sync_session_class` parameter.
-
-
- """
-
- _is_asyncio = True
-
- dispatch: dispatcher[Session]
-
- def __init__(
- self,
- bind: Optional[_AsyncSessionBind] = None,
- *,
- binds: Optional[Dict[_SessionBindKey, _AsyncSessionBind]] = None,
- sync_session_class: Optional[Type[Session]] = None,
- **kw: Any,
- ):
- r"""Construct a new :class:`_asyncio.AsyncSession`.
-
- All parameters other than ``sync_session_class`` are passed to the
- ``sync_session_class`` callable directly to instantiate a new
- :class:`_orm.Session`. Refer to :meth:`_orm.Session.__init__` for
- parameter documentation.
-
- :param sync_session_class:
- A :class:`_orm.Session` subclass or other callable which will be used
- to construct the :class:`_orm.Session` which will be proxied. This
- parameter may be used to provide custom :class:`_orm.Session`
- subclasses. Defaults to the
- :attr:`_asyncio.AsyncSession.sync_session_class` class-level
- attribute.
-
- .. versionadded:: 1.4.24
-
- """
- sync_bind = sync_binds = None
-
- if bind:
- self.bind = bind
- sync_bind = engine._get_sync_engine_or_connection(bind)
-
- if binds:
- self.binds = binds
- sync_binds = {
- key: engine._get_sync_engine_or_connection(b)
- for key, b in binds.items()
- }
-
- if sync_session_class:
- self.sync_session_class = sync_session_class
-
- self.sync_session = self._proxied = self._assign_proxied(
- self.sync_session_class(bind=sync_bind, binds=sync_binds, **kw)
- )
-
- sync_session_class: Type[Session] = Session
- """The class or callable that provides the
- underlying :class:`_orm.Session` instance for a particular
- :class:`_asyncio.AsyncSession`.
-
- At the class level, this attribute is the default value for the
- :paramref:`_asyncio.AsyncSession.sync_session_class` parameter. Custom
- subclasses of :class:`_asyncio.AsyncSession` can override this.
-
- At the instance level, this attribute indicates the current class or
- callable that was used to provide the :class:`_orm.Session` instance for
- this :class:`_asyncio.AsyncSession` instance.
-
- .. versionadded:: 1.4.24
-
- """
-
- sync_session: Session
- """Reference to the underlying :class:`_orm.Session` this
- :class:`_asyncio.AsyncSession` proxies requests towards.
-
- This instance can be used as an event target.
-
- .. seealso::
-
- :ref:`asyncio_events`
-
- """
-
- @classmethod
- def _no_async_engine_events(cls) -> NoReturn:
- raise NotImplementedError(
- "asynchronous events are not implemented at this time. Apply "
- "synchronous listeners to the AsyncSession.sync_session."
- )
-
- async def refresh(
- self,
- instance: object,
- attribute_names: Optional[Iterable[str]] = None,
- with_for_update: ForUpdateParameter = None,
- ) -> None:
- """Expire and refresh the attributes on the given instance.
-
- A query will be issued to the database and all attributes will be
- refreshed with their current database value.
-
- This is the async version of the :meth:`_orm.Session.refresh` method.
- See that method for a complete description of all options.
-
- .. seealso::
-
- :meth:`_orm.Session.refresh` - main documentation for refresh
-
- """
-
- await greenlet_spawn(
- self.sync_session.refresh,
- instance,
- attribute_names=attribute_names,
- with_for_update=with_for_update,
- )
-
- async def run_sync(
- self,
- fn: Callable[Concatenate[Session, _P], _T],
- *arg: _P.args,
- **kw: _P.kwargs,
- ) -> _T:
- """Invoke the given synchronous (i.e. not async) callable,
- passing a synchronous-style :class:`_orm.Session` as the first
- argument.
-
- This method allows traditional synchronous SQLAlchemy functions to
- run within the context of an asyncio application.
-
- E.g.::
-
- def some_business_method(session: Session, param: str) -> str:
- '''A synchronous function that does not require awaiting
-
- :param session: a SQLAlchemy Session, used synchronously
-
- :return: an optional return value is supported
-
- '''
- session.add(MyObject(param=param))
- session.flush()
- return "success"
-
-
- async def do_something_async(async_engine: AsyncEngine) -> None:
- '''an async function that uses awaiting'''
-
- with AsyncSession(async_engine) as async_session:
- # run some_business_method() with a sync-style
- # Session, proxied into an awaitable
- return_code = await async_session.run_sync(some_business_method, param="param1")
- print(return_code)
-
- This method maintains the asyncio event loop all the way through
- to the database connection by running the given callable in a
- specially instrumented greenlet.
-
- .. tip::
-
- The provided callable is invoked inline within the asyncio event
- loop, and will block on traditional IO calls. IO within this
- callable should only call into SQLAlchemy's asyncio database
- APIs which will be properly adapted to the greenlet context.
-
- .. seealso::
-
- :class:`.AsyncAttrs` - a mixin for ORM mapped classes that provides
- a similar feature more succinctly on a per-attribute basis
-
- :meth:`.AsyncConnection.run_sync`
-
- :ref:`session_run_sync`
- """ # noqa: E501
-
- return await greenlet_spawn(
- fn, self.sync_session, *arg, _require_await=False, **kw
- )
-
- @overload
- async def execute(
- self,
- statement: TypedReturnsRows[_T],
- params: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
- bind_arguments: Optional[_BindArguments] = None,
- _parent_execute_state: Optional[Any] = None,
- _add_event: Optional[Any] = None,
- ) -> Result[_T]: ...
-
- @overload
- async def execute(
- self,
- statement: UpdateBase,
- params: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
- bind_arguments: Optional[_BindArguments] = None,
- _parent_execute_state: Optional[Any] = None,
- _add_event: Optional[Any] = None,
- ) -> CursorResult[Any]: ...
-
- @overload
- async def execute(
- self,
- statement: Executable,
- params: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
- bind_arguments: Optional[_BindArguments] = None,
- _parent_execute_state: Optional[Any] = None,
- _add_event: Optional[Any] = None,
- ) -> Result[Any]: ...
-
- async def execute(
- self,
- statement: Executable,
- params: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
- bind_arguments: Optional[_BindArguments] = None,
- **kw: Any,
- ) -> Result[Any]:
- """Execute a statement and return a buffered
- :class:`_engine.Result` object.
-
- .. seealso::
-
- :meth:`_orm.Session.execute` - main documentation for execute
-
- """
-
- if execution_options:
- execution_options = util.immutabledict(execution_options).union(
- _EXECUTE_OPTIONS
- )
- else:
- execution_options = _EXECUTE_OPTIONS
-
- result = await greenlet_spawn(
- self.sync_session.execute,
- statement,
- params=params,
- execution_options=execution_options,
- bind_arguments=bind_arguments,
- **kw,
- )
- return await _ensure_sync_result(result, self.execute)
-
- @overload
- async def scalar(
- self,
- statement: TypedReturnsRows[Tuple[_T]],
- params: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
- bind_arguments: Optional[_BindArguments] = None,
- **kw: Any,
- ) -> Optional[_T]: ...
-
- @overload
- async def scalar(
- self,
- statement: Executable,
- params: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
- bind_arguments: Optional[_BindArguments] = None,
- **kw: Any,
- ) -> Any: ...
-
- async def scalar(
- self,
- statement: Executable,
- params: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
- bind_arguments: Optional[_BindArguments] = None,
- **kw: Any,
- ) -> Any:
- """Execute a statement and return a scalar result.
-
- .. seealso::
-
- :meth:`_orm.Session.scalar` - main documentation for scalar
-
- """
-
- if execution_options:
- execution_options = util.immutabledict(execution_options).union(
- _EXECUTE_OPTIONS
- )
- else:
- execution_options = _EXECUTE_OPTIONS
-
- return await greenlet_spawn(
- self.sync_session.scalar,
- statement,
- params=params,
- execution_options=execution_options,
- bind_arguments=bind_arguments,
- **kw,
- )
-
- @overload
- async def scalars(
- self,
- statement: TypedReturnsRows[Tuple[_T]],
- params: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
- bind_arguments: Optional[_BindArguments] = None,
- **kw: Any,
- ) -> ScalarResult[_T]: ...
-
- @overload
- async def scalars(
- self,
- statement: Executable,
- params: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
- bind_arguments: Optional[_BindArguments] = None,
- **kw: Any,
- ) -> ScalarResult[Any]: ...
-
- async def scalars(
- self,
- statement: Executable,
- params: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
- bind_arguments: Optional[_BindArguments] = None,
- **kw: Any,
- ) -> ScalarResult[Any]:
- """Execute a statement and return scalar results.
-
- :return: a :class:`_result.ScalarResult` object
-
- .. versionadded:: 1.4.24 Added :meth:`_asyncio.AsyncSession.scalars`
-
- .. versionadded:: 1.4.26 Added
- :meth:`_asyncio.async_scoped_session.scalars`
-
- .. seealso::
-
- :meth:`_orm.Session.scalars` - main documentation for scalars
-
- :meth:`_asyncio.AsyncSession.stream_scalars` - streaming version
-
- """
-
- result = await self.execute(
- statement,
- params=params,
- execution_options=execution_options,
- bind_arguments=bind_arguments,
- **kw,
- )
- return result.scalars()
-
- async def get(
- self,
- entity: _EntityBindKey[_O],
- ident: _PKIdentityArgument,
- *,
- options: Optional[Sequence[ORMOption]] = None,
- populate_existing: bool = False,
- with_for_update: ForUpdateParameter = None,
- identity_token: Optional[Any] = None,
- execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
- ) -> Union[_O, None]:
- """Return an instance based on the given primary key identifier,
- or ``None`` if not found.
-
- .. seealso::
-
- :meth:`_orm.Session.get` - main documentation for get
-
-
- """
-
- return await greenlet_spawn(
- cast("Callable[..., _O]", self.sync_session.get),
- entity,
- ident,
- options=options,
- populate_existing=populate_existing,
- with_for_update=with_for_update,
- identity_token=identity_token,
- execution_options=execution_options,
- )
-
- async def get_one(
- self,
- entity: _EntityBindKey[_O],
- ident: _PKIdentityArgument,
- *,
- options: Optional[Sequence[ORMOption]] = None,
- populate_existing: bool = False,
- with_for_update: ForUpdateParameter = None,
- identity_token: Optional[Any] = None,
- execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
- ) -> _O:
- """Return an instance based on the given primary key identifier,
- or raise an exception if not found.
-
- Raises ``sqlalchemy.orm.exc.NoResultFound`` if the query selects
- no rows.
-
- ..versionadded: 2.0.22
-
- .. seealso::
-
- :meth:`_orm.Session.get_one` - main documentation for get_one
-
- """
-
- return await greenlet_spawn(
- cast("Callable[..., _O]", self.sync_session.get_one),
- entity,
- ident,
- options=options,
- populate_existing=populate_existing,
- with_for_update=with_for_update,
- identity_token=identity_token,
- execution_options=execution_options,
- )
-
- @overload
- async def stream(
- self,
- statement: TypedReturnsRows[_T],
- params: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
- bind_arguments: Optional[_BindArguments] = None,
- **kw: Any,
- ) -> AsyncResult[_T]: ...
-
- @overload
- async def stream(
- self,
- statement: Executable,
- params: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
- bind_arguments: Optional[_BindArguments] = None,
- **kw: Any,
- ) -> AsyncResult[Any]: ...
-
- async def stream(
- self,
- statement: Executable,
- params: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
- bind_arguments: Optional[_BindArguments] = None,
- **kw: Any,
- ) -> AsyncResult[Any]:
- """Execute a statement and return a streaming
- :class:`_asyncio.AsyncResult` object.
-
- """
-
- if execution_options:
- execution_options = util.immutabledict(execution_options).union(
- _STREAM_OPTIONS
- )
- else:
- execution_options = _STREAM_OPTIONS
-
- result = await greenlet_spawn(
- self.sync_session.execute,
- statement,
- params=params,
- execution_options=execution_options,
- bind_arguments=bind_arguments,
- **kw,
- )
- return AsyncResult(result)
-
- @overload
- async def stream_scalars(
- self,
- statement: TypedReturnsRows[Tuple[_T]],
- params: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
- bind_arguments: Optional[_BindArguments] = None,
- **kw: Any,
- ) -> AsyncScalarResult[_T]: ...
-
- @overload
- async def stream_scalars(
- self,
- statement: Executable,
- params: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
- bind_arguments: Optional[_BindArguments] = None,
- **kw: Any,
- ) -> AsyncScalarResult[Any]: ...
-
- async def stream_scalars(
- self,
- statement: Executable,
- params: Optional[_CoreAnyExecuteParams] = None,
- *,
- execution_options: OrmExecuteOptionsParameter = util.EMPTY_DICT,
- bind_arguments: Optional[_BindArguments] = None,
- **kw: Any,
- ) -> AsyncScalarResult[Any]:
- """Execute a statement and return a stream of scalar results.
-
- :return: an :class:`_asyncio.AsyncScalarResult` object
-
- .. versionadded:: 1.4.24
-
- .. seealso::
-
- :meth:`_orm.Session.scalars` - main documentation for scalars
-
- :meth:`_asyncio.AsyncSession.scalars` - non streaming version
-
- """
-
- result = await self.stream(
- statement,
- params=params,
- execution_options=execution_options,
- bind_arguments=bind_arguments,
- **kw,
- )
- return result.scalars()
-
- async def delete(self, instance: object) -> None:
- """Mark an instance as deleted.
-
- The database delete operation occurs upon ``flush()``.
-
- As this operation may need to cascade along unloaded relationships,
- it is awaitable to allow for those queries to take place.
-
- .. seealso::
-
- :meth:`_orm.Session.delete` - main documentation for delete
-
- """
- await greenlet_spawn(self.sync_session.delete, instance)
-
- async def merge(
- self,
- instance: _O,
- *,
- load: bool = True,
- options: Optional[Sequence[ORMOption]] = None,
- ) -> _O:
- """Copy the state of a given instance into a corresponding instance
- within this :class:`_asyncio.AsyncSession`.
-
- .. seealso::
-
- :meth:`_orm.Session.merge` - main documentation for merge
-
- """
- return await greenlet_spawn(
- self.sync_session.merge, instance, load=load, options=options
- )
-
- async def flush(self, objects: Optional[Sequence[Any]] = None) -> None:
- """Flush all the object changes to the database.
-
- .. seealso::
-
- :meth:`_orm.Session.flush` - main documentation for flush
-
- """
- await greenlet_spawn(self.sync_session.flush, objects=objects)
-
- def get_transaction(self) -> Optional[AsyncSessionTransaction]:
- """Return the current root transaction in progress, if any.
-
- :return: an :class:`_asyncio.AsyncSessionTransaction` object, or
- ``None``.
-
- .. versionadded:: 1.4.18
-
- """
- trans = self.sync_session.get_transaction()
- if trans is not None:
- return AsyncSessionTransaction._retrieve_proxy_for_target(trans)
- else:
- return None
-
- def get_nested_transaction(self) -> Optional[AsyncSessionTransaction]:
- """Return the current nested transaction in progress, if any.
-
- :return: an :class:`_asyncio.AsyncSessionTransaction` object, or
- ``None``.
-
- .. versionadded:: 1.4.18
-
- """
-
- trans = self.sync_session.get_nested_transaction()
- if trans is not None:
- return AsyncSessionTransaction._retrieve_proxy_for_target(trans)
- else:
- return None
-
- def get_bind(
- self,
- mapper: Optional[_EntityBindKey[_O]] = None,
- clause: Optional[ClauseElement] = None,
- bind: Optional[_SessionBind] = None,
- **kw: Any,
- ) -> Union[Engine, Connection]:
- """Return a "bind" to which the synchronous proxied :class:`_orm.Session`
- is bound.
-
- Unlike the :meth:`_orm.Session.get_bind` method, this method is
- currently **not** used by this :class:`.AsyncSession` in any way
- in order to resolve engines for requests.
-
- .. note::
-
- This method proxies directly to the :meth:`_orm.Session.get_bind`
- method, however is currently **not** useful as an override target,
- in contrast to that of the :meth:`_orm.Session.get_bind` method.
- The example below illustrates how to implement custom
- :meth:`_orm.Session.get_bind` schemes that work with
- :class:`.AsyncSession` and :class:`.AsyncEngine`.
-
- The pattern introduced at :ref:`session_custom_partitioning`
- illustrates how to apply a custom bind-lookup scheme to a
- :class:`_orm.Session` given a set of :class:`_engine.Engine` objects.
- To apply a corresponding :meth:`_orm.Session.get_bind` implementation
- for use with a :class:`.AsyncSession` and :class:`.AsyncEngine`
- objects, continue to subclass :class:`_orm.Session` and apply it to
- :class:`.AsyncSession` using
- :paramref:`.AsyncSession.sync_session_class`. The inner method must
- continue to return :class:`_engine.Engine` instances, which can be
- acquired from a :class:`_asyncio.AsyncEngine` using the
- :attr:`_asyncio.AsyncEngine.sync_engine` attribute::
-
- # using example from "Custom Vertical Partitioning"
-
-
- import random
-
- from sqlalchemy.ext.asyncio import AsyncSession
- from sqlalchemy.ext.asyncio import create_async_engine
- from sqlalchemy.ext.asyncio import async_sessionmaker
- from sqlalchemy.orm import Session
-
- # construct async engines w/ async drivers
- engines = {
- 'leader':create_async_engine("sqlite+aiosqlite:///leader.db"),
- 'other':create_async_engine("sqlite+aiosqlite:///other.db"),
- 'follower1':create_async_engine("sqlite+aiosqlite:///follower1.db"),
- 'follower2':create_async_engine("sqlite+aiosqlite:///follower2.db"),
- }
-
- class RoutingSession(Session):
- def get_bind(self, mapper=None, clause=None, **kw):
- # within get_bind(), return sync engines
- if mapper and issubclass(mapper.class_, MyOtherClass):
- return engines['other'].sync_engine
- elif self._flushing or isinstance(clause, (Update, Delete)):
- return engines['leader'].sync_engine
- else:
- return engines[
- random.choice(['follower1','follower2'])
- ].sync_engine
-
- # apply to AsyncSession using sync_session_class
- AsyncSessionMaker = async_sessionmaker(
- sync_session_class=RoutingSession
- )
-
- The :meth:`_orm.Session.get_bind` method is called in a non-asyncio,
- implicitly non-blocking context in the same manner as ORM event hooks
- and functions that are invoked via :meth:`.AsyncSession.run_sync`, so
- routines that wish to run SQL commands inside of
- :meth:`_orm.Session.get_bind` can continue to do so using
- blocking-style code, which will be translated to implicitly async calls
- at the point of invoking IO on the database drivers.
-
- """ # noqa: E501
-
- return self.sync_session.get_bind(
- mapper=mapper, clause=clause, bind=bind, **kw
- )
-
- async def connection(
- self,
- bind_arguments: Optional[_BindArguments] = None,
- execution_options: Optional[CoreExecuteOptionsParameter] = None,
- **kw: Any,
- ) -> AsyncConnection:
- r"""Return a :class:`_asyncio.AsyncConnection` object corresponding to
- this :class:`.Session` object's transactional state.
-
- This method may also be used to establish execution options for the
- database connection used by the current transaction.
-
- .. versionadded:: 1.4.24 Added \**kw arguments which are passed
- through to the underlying :meth:`_orm.Session.connection` method.
-
- .. seealso::
-
- :meth:`_orm.Session.connection` - main documentation for
- "connection"
-
- """
-
- sync_connection = await greenlet_spawn(
- self.sync_session.connection,
- bind_arguments=bind_arguments,
- execution_options=execution_options,
- **kw,
- )
- return engine.AsyncConnection._retrieve_proxy_for_target(
- sync_connection
- )
-
- def begin(self) -> AsyncSessionTransaction:
- """Return an :class:`_asyncio.AsyncSessionTransaction` object.
-
- The underlying :class:`_orm.Session` will perform the
- "begin" action when the :class:`_asyncio.AsyncSessionTransaction`
- object is entered::
-
- async with async_session.begin():
- # .. ORM transaction is begun
-
- Note that database IO will not normally occur when the session-level
- transaction is begun, as database transactions begin on an
- on-demand basis. However, the begin block is async to accommodate
- for a :meth:`_orm.SessionEvents.after_transaction_create`
- event hook that may perform IO.
-
- For a general description of ORM begin, see
- :meth:`_orm.Session.begin`.
-
- """
-
- return AsyncSessionTransaction(self)
-
- def begin_nested(self) -> AsyncSessionTransaction:
- """Return an :class:`_asyncio.AsyncSessionTransaction` object
- which will begin a "nested" transaction, e.g. SAVEPOINT.
-
- Behavior is the same as that of :meth:`_asyncio.AsyncSession.begin`.
-
- For a general description of ORM begin nested, see
- :meth:`_orm.Session.begin_nested`.
-
- .. seealso::
-
- :ref:`aiosqlite_serializable` - special workarounds required
- with the SQLite asyncio driver in order for SAVEPOINT to work
- correctly.
-
- """
-
- return AsyncSessionTransaction(self, nested=True)
-
- async def rollback(self) -> None:
- """Rollback the current transaction in progress.
-
- .. seealso::
-
- :meth:`_orm.Session.rollback` - main documentation for
- "rollback"
- """
- await greenlet_spawn(self.sync_session.rollback)
-
- async def commit(self) -> None:
- """Commit the current transaction in progress.
-
- .. seealso::
-
- :meth:`_orm.Session.commit` - main documentation for
- "commit"
- """
- await greenlet_spawn(self.sync_session.commit)
-
- async def close(self) -> None:
- """Close out the transactional resources and ORM objects used by this
- :class:`_asyncio.AsyncSession`.
-
- .. seealso::
-
- :meth:`_orm.Session.close` - main documentation for
- "close"
-
- :ref:`session_closing` - detail on the semantics of
- :meth:`_asyncio.AsyncSession.close` and
- :meth:`_asyncio.AsyncSession.reset`.
-
- """
- await greenlet_spawn(self.sync_session.close)
-
- async def reset(self) -> None:
- """Close out the transactional resources and ORM objects used by this
- :class:`_orm.Session`, resetting the session to its initial state.
-
- .. versionadded:: 2.0.22
-
- .. seealso::
-
- :meth:`_orm.Session.reset` - main documentation for
- "reset"
-
- :ref:`session_closing` - detail on the semantics of
- :meth:`_asyncio.AsyncSession.close` and
- :meth:`_asyncio.AsyncSession.reset`.
-
- """
- await greenlet_spawn(self.sync_session.reset)
-
- async def aclose(self) -> None:
- """A synonym for :meth:`_asyncio.AsyncSession.close`.
-
- The :meth:`_asyncio.AsyncSession.aclose` name is specifically
- to support the Python standard library ``@contextlib.aclosing``
- context manager function.
-
- .. versionadded:: 2.0.20
-
- """
- await self.close()
-
- async def invalidate(self) -> None:
- """Close this Session, using connection invalidation.
-
- For a complete description, see :meth:`_orm.Session.invalidate`.
- """
- await greenlet_spawn(self.sync_session.invalidate)
-
- @classmethod
- @util.deprecated(
- "2.0",
- "The :meth:`.AsyncSession.close_all` method is deprecated and will be "
- "removed in a future release. Please refer to "
- ":func:`_asyncio.close_all_sessions`.",
- )
- async def close_all(cls) -> None:
- """Close all :class:`_asyncio.AsyncSession` sessions."""
- await close_all_sessions()
-
- async def __aenter__(self: _AS) -> _AS:
- return self
-
- async def __aexit__(self, type_: Any, value: Any, traceback: Any) -> None:
- task = asyncio.create_task(self.close())
- await asyncio.shield(task)
-
- def _maker_context_manager(self: _AS) -> _AsyncSessionContextManager[_AS]:
- return _AsyncSessionContextManager(self)
-
- # START PROXY METHODS AsyncSession
-
- # code within this block is **programmatically,
- # statically generated** by tools/generate_proxy_methods.py
-
- def __contains__(self, instance: object) -> bool:
- r"""Return True if the instance is associated with this session.
-
- .. container:: class_bases
-
- Proxied for the :class:`_orm.Session` class on
- behalf of the :class:`_asyncio.AsyncSession` class.
-
- The instance may be pending or persistent within the Session for a
- result of True.
-
-
- """ # noqa: E501
-
- return self._proxied.__contains__(instance)
-
- def __iter__(self) -> Iterator[object]:
- r"""Iterate over all pending or persistent instances within this
- Session.
-
- .. container:: class_bases
-
- Proxied for the :class:`_orm.Session` class on
- behalf of the :class:`_asyncio.AsyncSession` class.
-
-
- """ # noqa: E501
-
- return self._proxied.__iter__()
-
- def add(self, instance: object, _warn: bool = True) -> None:
- r"""Place an object into this :class:`_orm.Session`.
-
- .. container:: class_bases
-
- Proxied for the :class:`_orm.Session` class on
- behalf of the :class:`_asyncio.AsyncSession` class.
-
- Objects that are in the :term:`transient` state when passed to the
- :meth:`_orm.Session.add` method will move to the
- :term:`pending` state, until the next flush, at which point they
- will move to the :term:`persistent` state.
-
- Objects that are in the :term:`detached` state when passed to the
- :meth:`_orm.Session.add` method will move to the :term:`persistent`
- state directly.
-
- If the transaction used by the :class:`_orm.Session` is rolled back,
- objects which were transient when they were passed to
- :meth:`_orm.Session.add` will be moved back to the
- :term:`transient` state, and will no longer be present within this
- :class:`_orm.Session`.
-
- .. seealso::
-
- :meth:`_orm.Session.add_all`
-
- :ref:`session_adding` - at :ref:`session_basics`
-
-
- """ # noqa: E501
-
- return self._proxied.add(instance, _warn=_warn)
-
- def add_all(self, instances: Iterable[object]) -> None:
- r"""Add the given collection of instances to this :class:`_orm.Session`.
-
- .. container:: class_bases
-
- Proxied for the :class:`_orm.Session` class on
- behalf of the :class:`_asyncio.AsyncSession` class.
-
- See the documentation for :meth:`_orm.Session.add` for a general
- behavioral description.
-
- .. seealso::
-
- :meth:`_orm.Session.add`
-
- :ref:`session_adding` - at :ref:`session_basics`
-
-
- """ # noqa: E501
-
- return self._proxied.add_all(instances)
-
- def expire(
- self, instance: object, attribute_names: Optional[Iterable[str]] = None
- ) -> None:
- r"""Expire the attributes on an instance.
-
- .. container:: class_bases
-
- Proxied for the :class:`_orm.Session` class on
- behalf of the :class:`_asyncio.AsyncSession` class.
-
- Marks the attributes of an instance as out of date. When an expired
- attribute is next accessed, a query will be issued to the
- :class:`.Session` object's current transactional context in order to
- load all expired attributes for the given instance. Note that
- a highly isolated transaction will return the same values as were
- previously read in that same transaction, regardless of changes
- in database state outside of that transaction.
-
- To expire all objects in the :class:`.Session` simultaneously,
- use :meth:`Session.expire_all`.
-
- The :class:`.Session` object's default behavior is to
- expire all state whenever the :meth:`Session.rollback`
- or :meth:`Session.commit` methods are called, so that new
- state can be loaded for the new transaction. For this reason,
- calling :meth:`Session.expire` only makes sense for the specific
- case that a non-ORM SQL statement was emitted in the current
- transaction.
-
- :param instance: The instance to be refreshed.
- :param attribute_names: optional list of string attribute names
- indicating a subset of attributes to be expired.
-
- .. seealso::
-
- :ref:`session_expire` - introductory material
-
- :meth:`.Session.expire`
-
- :meth:`.Session.refresh`
-
- :meth:`_orm.Query.populate_existing`
-
-
- """ # noqa: E501
-
- return self._proxied.expire(instance, attribute_names=attribute_names)
-
- def expire_all(self) -> None:
- r"""Expires all persistent instances within this Session.
-
- .. container:: class_bases
-
- Proxied for the :class:`_orm.Session` class on
- behalf of the :class:`_asyncio.AsyncSession` class.
-
- When any attributes on a persistent instance is next accessed,
- a query will be issued using the
- :class:`.Session` object's current transactional context in order to
- load all expired attributes for the given instance. Note that
- a highly isolated transaction will return the same values as were
- previously read in that same transaction, regardless of changes
- in database state outside of that transaction.
-
- To expire individual objects and individual attributes
- on those objects, use :meth:`Session.expire`.
-
- The :class:`.Session` object's default behavior is to
- expire all state whenever the :meth:`Session.rollback`
- or :meth:`Session.commit` methods are called, so that new
- state can be loaded for the new transaction. For this reason,
- calling :meth:`Session.expire_all` is not usually needed,
- assuming the transaction is isolated.
-
- .. seealso::
-
- :ref:`session_expire` - introductory material
-
- :meth:`.Session.expire`
-
- :meth:`.Session.refresh`
-
- :meth:`_orm.Query.populate_existing`
-
-
- """ # noqa: E501
-
- return self._proxied.expire_all()
-
- def expunge(self, instance: object) -> None:
- r"""Remove the `instance` from this ``Session``.
-
- .. container:: class_bases
-
- Proxied for the :class:`_orm.Session` class on
- behalf of the :class:`_asyncio.AsyncSession` class.
-
- This will free all internal references to the instance. Cascading
- will be applied according to the *expunge* cascade rule.
-
-
- """ # noqa: E501
-
- return self._proxied.expunge(instance)
-
- def expunge_all(self) -> None:
- r"""Remove all object instances from this ``Session``.
-
- .. container:: class_bases
-
- Proxied for the :class:`_orm.Session` class on
- behalf of the :class:`_asyncio.AsyncSession` class.
-
- This is equivalent to calling ``expunge(obj)`` on all objects in this
- ``Session``.
-
-
- """ # noqa: E501
-
- return self._proxied.expunge_all()
-
- def is_modified(
- self, instance: object, include_collections: bool = True
- ) -> bool:
- r"""Return ``True`` if the given instance has locally
- modified attributes.
-
- .. container:: class_bases
-
- Proxied for the :class:`_orm.Session` class on
- behalf of the :class:`_asyncio.AsyncSession` class.
-
- This method retrieves the history for each instrumented
- attribute on the instance and performs a comparison of the current
- value to its previously committed value, if any.
-
- It is in effect a more expensive and accurate
- version of checking for the given instance in the
- :attr:`.Session.dirty` collection; a full test for
- each attribute's net "dirty" status is performed.
-
- E.g.::
-
- return session.is_modified(someobject)
-
- A few caveats to this method apply:
-
- * Instances present in the :attr:`.Session.dirty` collection may
- report ``False`` when tested with this method. This is because
- the object may have received change events via attribute mutation,
- thus placing it in :attr:`.Session.dirty`, but ultimately the state
- is the same as that loaded from the database, resulting in no net
- change here.
- * Scalar attributes may not have recorded the previously set
- value when a new value was applied, if the attribute was not loaded,
- or was expired, at the time the new value was received - in these
- cases, the attribute is assumed to have a change, even if there is
- ultimately no net change against its database value. SQLAlchemy in
- most cases does not need the "old" value when a set event occurs, so
- it skips the expense of a SQL call if the old value isn't present,
- based on the assumption that an UPDATE of the scalar value is
- usually needed, and in those few cases where it isn't, is less
- expensive on average than issuing a defensive SELECT.
-
- The "old" value is fetched unconditionally upon set only if the
- attribute container has the ``active_history`` flag set to ``True``.
- This flag is set typically for primary key attributes and scalar
- object references that are not a simple many-to-one. To set this
- flag for any arbitrary mapped column, use the ``active_history``
- argument with :func:`.column_property`.
-
- :param instance: mapped instance to be tested for pending changes.
- :param include_collections: Indicates if multivalued collections
- should be included in the operation. Setting this to ``False`` is a
- way to detect only local-column based properties (i.e. scalar columns
- or many-to-one foreign keys) that would result in an UPDATE for this
- instance upon flush.
-
-
- """ # noqa: E501
-
- return self._proxied.is_modified(
- instance, include_collections=include_collections
- )
-
- def in_transaction(self) -> bool:
- r"""Return True if this :class:`_orm.Session` has begun a transaction.
-
- .. container:: class_bases
-
- Proxied for the :class:`_orm.Session` class on
- behalf of the :class:`_asyncio.AsyncSession` class.
-
- .. versionadded:: 1.4
-
- .. seealso::
-
- :attr:`_orm.Session.is_active`
-
-
-
- """ # noqa: E501
-
- return self._proxied.in_transaction()
-
- def in_nested_transaction(self) -> bool:
- r"""Return True if this :class:`_orm.Session` has begun a nested
- transaction, e.g. SAVEPOINT.
-
- .. container:: class_bases
-
- Proxied for the :class:`_orm.Session` class on
- behalf of the :class:`_asyncio.AsyncSession` class.
-
- .. versionadded:: 1.4
-
-
- """ # noqa: E501
-
- return self._proxied.in_nested_transaction()
-
- @property
- def dirty(self) -> Any:
- r"""The set of all persistent instances considered dirty.
-
- .. container:: class_bases
-
- Proxied for the :class:`_orm.Session` class
- on behalf of the :class:`_asyncio.AsyncSession` class.
-
- E.g.::
-
- some_mapped_object in session.dirty
-
- Instances are considered dirty when they were modified but not
- deleted.
-
- Note that this 'dirty' calculation is 'optimistic'; most
- attribute-setting or collection modification operations will
- mark an instance as 'dirty' and place it in this set, even if
- there is no net change to the attribute's value. At flush
- time, the value of each attribute is compared to its
- previously saved value, and if there's no net change, no SQL
- operation will occur (this is a more expensive operation so
- it's only done at flush time).
-
- To check if an instance has actionable net changes to its
- attributes, use the :meth:`.Session.is_modified` method.
-
-
- """ # noqa: E501
-
- return self._proxied.dirty
-
- @property
- def deleted(self) -> Any:
- r"""The set of all instances marked as 'deleted' within this ``Session``
-
- .. container:: class_bases
-
- Proxied for the :class:`_orm.Session` class
- on behalf of the :class:`_asyncio.AsyncSession` class.
-
- """ # noqa: E501
-
- return self._proxied.deleted
-
- @property
- def new(self) -> Any:
- r"""The set of all instances marked as 'new' within this ``Session``.
-
- .. container:: class_bases
-
- Proxied for the :class:`_orm.Session` class
- on behalf of the :class:`_asyncio.AsyncSession` class.
-
- """ # noqa: E501
-
- return self._proxied.new
-
- @property
- def identity_map(self) -> IdentityMap:
- r"""Proxy for the :attr:`_orm.Session.identity_map` attribute
- on behalf of the :class:`_asyncio.AsyncSession` class.
-
- """ # noqa: E501
-
- return self._proxied.identity_map
-
- @identity_map.setter
- def identity_map(self, attr: IdentityMap) -> None:
- self._proxied.identity_map = attr
-
- @property
- def is_active(self) -> Any:
- r"""True if this :class:`.Session` not in "partial rollback" state.
-
- .. container:: class_bases
-
- Proxied for the :class:`_orm.Session` class
- on behalf of the :class:`_asyncio.AsyncSession` class.
-
- .. versionchanged:: 1.4 The :class:`_orm.Session` no longer begins
- a new transaction immediately, so this attribute will be False
- when the :class:`_orm.Session` is first instantiated.
-
- "partial rollback" state typically indicates that the flush process
- of the :class:`_orm.Session` has failed, and that the
- :meth:`_orm.Session.rollback` method must be emitted in order to
- fully roll back the transaction.
-
- If this :class:`_orm.Session` is not in a transaction at all, the
- :class:`_orm.Session` will autobegin when it is first used, so in this
- case :attr:`_orm.Session.is_active` will return True.
-
- Otherwise, if this :class:`_orm.Session` is within a transaction,
- and that transaction has not been rolled back internally, the
- :attr:`_orm.Session.is_active` will also return True.
-
- .. seealso::
-
- :ref:`faq_session_rollback`
-
- :meth:`_orm.Session.in_transaction`
-
-
- """ # noqa: E501
-
- return self._proxied.is_active
-
- @property
- def autoflush(self) -> bool:
- r"""Proxy for the :attr:`_orm.Session.autoflush` attribute
- on behalf of the :class:`_asyncio.AsyncSession` class.
-
- """ # noqa: E501
-
- return self._proxied.autoflush
-
- @autoflush.setter
- def autoflush(self, attr: bool) -> None:
- self._proxied.autoflush = attr
-
- @property
- def no_autoflush(self) -> Any:
- r"""Return a context manager that disables autoflush.
-
- .. container:: class_bases
-
- Proxied for the :class:`_orm.Session` class
- on behalf of the :class:`_asyncio.AsyncSession` class.
-
- e.g.::
-
- with session.no_autoflush:
-
- some_object = SomeClass()
- session.add(some_object)
- # won't autoflush
- some_object.related_thing = session.query(SomeRelated).first()
-
- Operations that proceed within the ``with:`` block
- will not be subject to flushes occurring upon query
- access. This is useful when initializing a series
- of objects which involve existing database queries,
- where the uncompleted object should not yet be flushed.
-
-
- """ # noqa: E501
-
- return self._proxied.no_autoflush
-
- @property
- def info(self) -> Any:
- r"""A user-modifiable dictionary.
-
- .. container:: class_bases
-
- Proxied for the :class:`_orm.Session` class
- on behalf of the :class:`_asyncio.AsyncSession` class.
-
- The initial value of this dictionary can be populated using the
- ``info`` argument to the :class:`.Session` constructor or
- :class:`.sessionmaker` constructor or factory methods. The dictionary
- here is always local to this :class:`.Session` and can be modified
- independently of all other :class:`.Session` objects.
-
-
- """ # noqa: E501
-
- return self._proxied.info
-
- @classmethod
- def object_session(cls, instance: object) -> Optional[Session]:
- r"""Return the :class:`.Session` to which an object belongs.
-
- .. container:: class_bases
-
- Proxied for the :class:`_orm.Session` class on
- behalf of the :class:`_asyncio.AsyncSession` class.
-
- This is an alias of :func:`.object_session`.
-
-
- """ # noqa: E501
-
- return Session.object_session(instance)
-
- @classmethod
- def identity_key(
- cls,
- class_: Optional[Type[Any]] = None,
- ident: Union[Any, Tuple[Any, ...]] = None,
- *,
- instance: Optional[Any] = None,
- row: Optional[Union[Row[Any], RowMapping]] = None,
- identity_token: Optional[Any] = None,
- ) -> _IdentityKeyType[Any]:
- r"""Return an identity key.
-
- .. container:: class_bases
-
- Proxied for the :class:`_orm.Session` class on
- behalf of the :class:`_asyncio.AsyncSession` class.
-
- This is an alias of :func:`.util.identity_key`.
-
-
- """ # noqa: E501
-
- return Session.identity_key(
- class_=class_,
- ident=ident,
- instance=instance,
- row=row,
- identity_token=identity_token,
- )
-
- # END PROXY METHODS AsyncSession
-
-
-_AS = TypeVar("_AS", bound="AsyncSession")
-
-
-class async_sessionmaker(Generic[_AS]):
- """A configurable :class:`.AsyncSession` factory.
-
- The :class:`.async_sessionmaker` factory works in the same way as the
- :class:`.sessionmaker` factory, to generate new :class:`.AsyncSession`
- objects when called, creating them given
- the configurational arguments established here.
-
- e.g.::
-
- from sqlalchemy.ext.asyncio import create_async_engine
- from sqlalchemy.ext.asyncio import AsyncSession
- from sqlalchemy.ext.asyncio import async_sessionmaker
-
- async def run_some_sql(async_session: async_sessionmaker[AsyncSession]) -> None:
- async with async_session() as session:
- session.add(SomeObject(data="object"))
- session.add(SomeOtherObject(name="other object"))
- await session.commit()
-
- async def main() -> None:
- # an AsyncEngine, which the AsyncSession will use for connection
- # resources
- engine = create_async_engine('postgresql+asyncpg://scott:tiger@localhost/')
-
- # create a reusable factory for new AsyncSession instances
- async_session = async_sessionmaker(engine)
-
- await run_some_sql(async_session)
-
- await engine.dispose()
-
- The :class:`.async_sessionmaker` is useful so that different parts
- of a program can create new :class:`.AsyncSession` objects with a
- fixed configuration established up front. Note that :class:`.AsyncSession`
- objects may also be instantiated directly when not using
- :class:`.async_sessionmaker`.
-
- .. versionadded:: 2.0 :class:`.async_sessionmaker` provides a
- :class:`.sessionmaker` class that's dedicated to the
- :class:`.AsyncSession` object, including pep-484 typing support.
-
- .. seealso::
-
- :ref:`asyncio_orm` - shows example use
-
- :class:`.sessionmaker` - general overview of the
- :class:`.sessionmaker` architecture
-
-
- :ref:`session_getting` - introductory text on creating
- sessions using :class:`.sessionmaker`.
-
- """ # noqa E501
-
- class_: Type[_AS]
-
- @overload
- def __init__(
- self,
- bind: Optional[_AsyncSessionBind] = ...,
- *,
- class_: Type[_AS],
- autoflush: bool = ...,
- expire_on_commit: bool = ...,
- info: Optional[_InfoType] = ...,
- **kw: Any,
- ): ...
-
- @overload
- def __init__(
- self: "async_sessionmaker[AsyncSession]",
- bind: Optional[_AsyncSessionBind] = ...,
- *,
- autoflush: bool = ...,
- expire_on_commit: bool = ...,
- info: Optional[_InfoType] = ...,
- **kw: Any,
- ): ...
-
- def __init__(
- self,
- bind: Optional[_AsyncSessionBind] = None,
- *,
- class_: Type[_AS] = AsyncSession, # type: ignore
- autoflush: bool = True,
- expire_on_commit: bool = True,
- info: Optional[_InfoType] = None,
- **kw: Any,
- ):
- r"""Construct a new :class:`.async_sessionmaker`.
-
- All arguments here except for ``class_`` correspond to arguments
- accepted by :class:`.Session` directly. See the
- :meth:`.AsyncSession.__init__` docstring for more details on
- parameters.
-
-
- """
- kw["bind"] = bind
- kw["autoflush"] = autoflush
- kw["expire_on_commit"] = expire_on_commit
- if info is not None:
- kw["info"] = info
- self.kw = kw
- self.class_ = class_
-
- def begin(self) -> _AsyncSessionContextManager[_AS]:
- """Produce a context manager that both provides a new
- :class:`_orm.AsyncSession` as well as a transaction that commits.
-
-
- e.g.::
-
- async def main():
- Session = async_sessionmaker(some_engine)
-
- async with Session.begin() as session:
- session.add(some_object)
-
- # commits transaction, closes session
-
-
- """
-
- session = self()
- return session._maker_context_manager()
-
- def __call__(self, **local_kw: Any) -> _AS:
- """Produce a new :class:`.AsyncSession` object using the configuration
- established in this :class:`.async_sessionmaker`.
-
- In Python, the ``__call__`` method is invoked on an object when
- it is "called" in the same way as a function::
-
- AsyncSession = async_sessionmaker(async_engine, expire_on_commit=False)
- session = AsyncSession() # invokes sessionmaker.__call__()
-
- """ # noqa E501
- for k, v in self.kw.items():
- if k == "info" and "info" in local_kw:
- d = v.copy()
- d.update(local_kw["info"])
- local_kw["info"] = d
- else:
- local_kw.setdefault(k, v)
- return self.class_(**local_kw)
-
- def configure(self, **new_kw: Any) -> None:
- """(Re)configure the arguments for this async_sessionmaker.
-
- e.g.::
-
- AsyncSession = async_sessionmaker(some_engine)
-
- AsyncSession.configure(bind=create_async_engine('sqlite+aiosqlite://'))
- """ # noqa E501
-
- self.kw.update(new_kw)
-
- def __repr__(self) -> str:
- return "%s(class_=%r, %s)" % (
- self.__class__.__name__,
- self.class_.__name__,
- ", ".join("%s=%r" % (k, v) for k, v in self.kw.items()),
- )
-
-
-class _AsyncSessionContextManager(Generic[_AS]):
- __slots__ = ("async_session", "trans")
-
- async_session: _AS
- trans: AsyncSessionTransaction
-
- def __init__(self, async_session: _AS):
- self.async_session = async_session
-
- async def __aenter__(self) -> _AS:
- self.trans = self.async_session.begin()
- await self.trans.__aenter__()
- return self.async_session
-
- async def __aexit__(self, type_: Any, value: Any, traceback: Any) -> None:
- async def go() -> None:
- await self.trans.__aexit__(type_, value, traceback)
- await self.async_session.__aexit__(type_, value, traceback)
-
- task = asyncio.create_task(go())
- await asyncio.shield(task)
-
-
-class AsyncSessionTransaction(
- ReversibleProxy[SessionTransaction],
- StartableContext["AsyncSessionTransaction"],
-):
- """A wrapper for the ORM :class:`_orm.SessionTransaction` object.
-
- This object is provided so that a transaction-holding object
- for the :meth:`_asyncio.AsyncSession.begin` may be returned.
-
- The object supports both explicit calls to
- :meth:`_asyncio.AsyncSessionTransaction.commit` and
- :meth:`_asyncio.AsyncSessionTransaction.rollback`, as well as use as an
- async context manager.
-
-
- .. versionadded:: 1.4
-
- """
-
- __slots__ = ("session", "sync_transaction", "nested")
-
- session: AsyncSession
- sync_transaction: Optional[SessionTransaction]
-
- def __init__(self, session: AsyncSession, nested: bool = False):
- self.session = session
- self.nested = nested
- self.sync_transaction = None
-
- @property
- def is_active(self) -> bool:
- return (
- self._sync_transaction() is not None
- and self._sync_transaction().is_active
- )
-
- def _sync_transaction(self) -> SessionTransaction:
- if not self.sync_transaction:
- self._raise_for_not_started()
- return self.sync_transaction
-
- async def rollback(self) -> None:
- """Roll back this :class:`_asyncio.AsyncTransaction`."""
- await greenlet_spawn(self._sync_transaction().rollback)
-
- async def commit(self) -> None:
- """Commit this :class:`_asyncio.AsyncTransaction`."""
-
- await greenlet_spawn(self._sync_transaction().commit)
-
- async def start(
- self, is_ctxmanager: bool = False
- ) -> AsyncSessionTransaction:
- self.sync_transaction = self._assign_proxied(
- await greenlet_spawn(
- self.session.sync_session.begin_nested # type: ignore
- if self.nested
- else self.session.sync_session.begin
- )
- )
- if is_ctxmanager:
- self.sync_transaction.__enter__()
- return self
-
- async def __aexit__(self, type_: Any, value: Any, traceback: Any) -> None:
- await greenlet_spawn(
- self._sync_transaction().__exit__, type_, value, traceback
- )
-
-
-def async_object_session(instance: object) -> Optional[AsyncSession]:
- """Return the :class:`_asyncio.AsyncSession` to which the given instance
- belongs.
-
- This function makes use of the sync-API function
- :class:`_orm.object_session` to retrieve the :class:`_orm.Session` which
- refers to the given instance, and from there links it to the original
- :class:`_asyncio.AsyncSession`.
-
- If the :class:`_asyncio.AsyncSession` has been garbage collected, the
- return value is ``None``.
-
- This functionality is also available from the
- :attr:`_orm.InstanceState.async_session` accessor.
-
- :param instance: an ORM mapped instance
- :return: an :class:`_asyncio.AsyncSession` object, or ``None``.
-
- .. versionadded:: 1.4.18
-
- """
-
- session = object_session(instance)
- if session is not None:
- return async_session(session)
- else:
- return None
-
-
-def async_session(session: Session) -> Optional[AsyncSession]:
- """Return the :class:`_asyncio.AsyncSession` which is proxying the given
- :class:`_orm.Session` object, if any.
-
- :param session: a :class:`_orm.Session` instance.
- :return: a :class:`_asyncio.AsyncSession` instance, or ``None``.
-
- .. versionadded:: 1.4.18
-
- """
- return AsyncSession._retrieve_proxy_for_target(session, regenerate=False)
-
-
-async def close_all_sessions() -> None:
- """Close all :class:`_asyncio.AsyncSession` sessions.
-
- .. versionadded:: 2.0.23
-
- .. seealso::
-
- :func:`.session.close_all_sessions`
-
- """
- await greenlet_spawn(_sync_close_all_sessions)
-
-
-_instance_state._async_provider = async_session # type: ignore