#CODE: class AsyncSession(ReversibleProxy[Session]):
async def __aexit__(self, type_: Any, value: Any, traceback: Any) -> None:
task = asyncio.create_task(self.close())
await asyncio.shield(task)
#CODE: class AsyncSession(ReversibleProxy[Session]):
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)
# CODE: class AsyncSessionTransaction
async def __aexit__(self, type_: Any, value: Any, traceback: Any) -> None:
await greenlet_spawn(
self._sync_transaction().__exit__, type_, value, traceback
)
def __exit__(self, type_: Any, value: Any, traceback: Any) -> None:
subject = getattr(self, "_trans_subject", None)
# simplistically we could assume that
# "subject._trans_context_manager is self". However, any calling
# code that is manipulating __exit__ directly would break this
# assumption. alembic context manager
# is an example of partial use that just calls __exit__ and
# not __enter__ at the moment. it's safe to assume this is being done
# in the wild also
out_of_band_exit = (
subject is None or subject._trans_context_manager is not self
)
if type_ is None and self._transaction_is_active():
try:
self.commit()
except:
with util.safe_reraise():
if self._rollback_can_be_called():
self.rollback()
finally:
if not out_of_band_exit:
assert subject is not None
subject._trans_context_manager = self._outer_trans_ctx
self._trans_subject = self._outer_trans_ctx = None
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 __exit__(self, type_: Any, value: Any, traceback: Any) -> None:
subject = getattr(self, "_trans_subject", None)
# simplistically we could assume that
# "subject._trans_context_manager is self". However, any calling
# code that is manipulating __exit__ directly would break this
# assumption. alembic context manager
# is an example of partial use that just calls __exit__ and
# not __enter__ at the moment. it's safe to assume this is being done
# in the wild also
out_of_band_exit = (
subject is None or subject._trans_context_manager is not self
)
if type_ is None and self._transaction_is_active():
try:
self.commit()
...................
Алан Гибизов, тут просто замена этого метода, интересно чуть глубже, заменить __get__, который вызывается классом О_О