
    +h^              	       r   d dl Z ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ dd	lm	Z	 dd
l
mZ ddl
mZ ddl
mZ ddlmZ  e	j"                  ddi      Z e	j"                  ddi      Z e	j(                  eddddgg dg d       G d de             Z G d d      Z G d dee      Zd Zd Zee_        y)     N   )engine)result)ReversibleProxy)StartableContext)_ensure_sync_result   )util)object_session)Session)state)greenlet_spawnprebuffer_rowsTstream_resultsz:class:`_orm.Session`z:class:`_asyncio.AsyncSession`r   identity_key)__contains____iter__addadd_allexpire
expire_allexpungeexpunge_allis_modifiedin_transactionin_nested_transaction)dirtydeletednewidentity_map	is_active	autoflushno_autoflushinfo)classmethodsmethods
attributesc                   t   e Zd ZU dZdZdZddZeZ	 ee	d<   	 	 d dZ
d Zdej                  dfdZdej                  dfd	Zdej                  dfd
Z	 	 	 	 d!dZdej                  dfdZdej                  dfdZd Zd"dZd#dZd Zd ZddZd Zd Zd Zd Zd Zd Zd Z e!d        Z"d Z#d Z$d Z%y)$AsyncSessionae  Asyncio version of :class:`_orm.Session`.

    The :class:`_asyncio.AsyncSession` is a proxy for a traditional
    :class:`_orm.Session` instance.

    .. versionadded:: 1.4

    To use an :class:`_asyncio.AsyncSession` with custom :class:`_orm.Session`
    implementations, see the
    :paramref:`_asyncio.AsyncSession.sync_session_class` parameter.


    TNc                 F   d|d<   |r|| _         t        j                  |      }|r=|| _        |j	                         D ci c]  \  }}|t        j                  |       }}}|r|| _        | j                   | j
                  d||d|      x| _        | _        yc c}}w )a  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

        Tfuture)bindbindsN )	r,   r   _get_sync_engine_or_connectionr-   itemssync_session_class_assign_proxiedsync_session_proxied)selfr,   r-   r1   kwkeybs          Q/var/www/html/venv/lib/python3.12/site-packages/sqlalchemy/ext/asyncio/session.py__init__zAsyncSession.__init__H   s    & 8DI88>DDJ $kkmC V::1==E 
 &8D#,0,@,@#D##AUAbA-
 	
DMs     Br3   c                 d   K   t        | j                  j                  |||       d{   S 7 w)a  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

        )attribute_nameswith_for_updateN)r   r3   refresh)r5   instancer<   r=   s       r9   r>   zAsyncSession.refresh   s7     " $%%++	
 
 	
 
   '0.0c                 R   K   t        || j                  g|i | d{   S 7 w)a  Invoke the given sync callable passing sync self as the first
        argument.

        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.

        E.g.::

            with AsyncSession(async_engine) as session:
                await session.run_sync(some_business_method)

        .. 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::

            :ref:`session_run_sync`
        N)r   r3   )r5   fnargr6   s       r9   run_synczAsyncSession.run_sync   s+     2 $B(9(9FCF2FFFFs   '%'c                 
  K   |r)t        j                  |      j                  t              }nt        }t	        | j
                  j                  |f|||d| d{   }t        || j                         d{   S 7 "7 w)zExecute a statement and return a buffered
        :class:`_engine.Result` object.

        .. seealso::

            :meth:`_orm.Session.execute` - main documentation for execute

        paramsexecution_optionsbind_argumentsN)r
   immutabledictunion_EXECUTE_OPTIONSr   r3   executer   r5   	statementrG   rH   rI   r6   r   s          r9   rM   zAsyncSession.execute   s     "  $ 2 23D E K K ! !1%%%
 /)
 
 
 )>>>
 ?s$   ABA?B:B;BBc                 l   K    | j                   |f|||d| d{   }|j                         S 7 w)zExecute a statement and return a scalar result.

        .. seealso::

            :meth:`_orm.Session.scalar` - main documentation for scalar

        rF   N)rM   scalarrN   s          r9   rQ   zAsyncSession.scalar   sK       $t||
/)	

 
 
 }}
   424c                 l   K    | j                   |f|||d| d{   }|j                         S 7 w)a  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

        rF   N)rM   scalarsrN   s          r9   rT   zAsyncSession.scalars   sL     2 $t||
/)	

 
 
 ~~
rR   c           	      j   K   t        | j                  j                  ||||||       d{   S 7 w)zReturn an instance based on the given primary key identifier,
        or ``None`` if not found.

        .. seealso::

            :meth:`_orm.Session.get` - main documentation for get


        )optionspopulate_existingr=   identity_tokenN)r   r3   get)r5   entityidentrV   rW   r=   rX   s          r9   rY   zAsyncSession.get  s@     $ $!!/+)
 
 	
 
s   *313c                    K   |r)t        j                  |      j                  t              }nt        }t	        | j
                  j                  |f|||d| d{   }t        j                  |      S 7 w)zbExecute a statement and return a streaming
        :class:`_asyncio.AsyncResult` object.

        rF   N)	r
   rJ   rK   _STREAM_OPTIONSr   r3   rM   _resultAsyncResultrN   s          r9   streamzAsyncSession.stream7  s       $ 2 23D E K K! !0%%%
 /)
 
 
 ""6**
s   AA8A6A8c                 l   K    | j                   |f|||d| d{   }|j                         S 7 w)aR  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

        rF   N)r`   rT   rN   s          r9   stream_scalarszAsyncSession.stream_scalarsU  sL     , #t{{
/)	

 
 
 ~~
rR   c                 ^   K   t        | j                  j                  |       d{   S 7 w)aT  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

        N)r   r3   delete)r5   r?   s     r9   rd   zAsyncSession.deletet  s'      $D$5$5$<$<hGGGGs   $-+-c                 d   K   t        | j                  j                  |||       d{   S 7 w)zCopy the state of a given instance into a corresponding instance
        within this :class:`_asyncio.AsyncSession`.

        .. seealso::

            :meth:`_orm.Session.merge` - main documentation for merge

        )loadrV   N)r   r3   merge)r5   r?   rf   rV   s       r9   rg   zAsyncSession.merge  s4      $##XD'
 
 	
 
r@   c                 b   K   t        | j                  j                  |       d{    y7 w)zFlush all the object changes to the database.

        .. seealso::

            :meth:`_orm.Session.flush` - main documentation for flush

        )objectsN)r   r3   flush)r5   ri   s     r9   rj   zAsyncSession.flush  s$      T..44gFFFs   %/-/c                 f    | j                   j                         }|t        j                  |      S y)zReturn the current root transaction in progress, if any.

        :return: an :class:`_asyncio.AsyncSessionTransaction` object, or
         ``None``.

        .. versionadded:: 1.4.18

        N)r3   get_transactionAsyncSessionTransaction_retrieve_proxy_for_targetr5   transs     r9   rl   zAsyncSession.get_transaction  s2     !!113*EEeLL    c                 f    | j                   j                         }|t        j                  |      S y)zReturn the current nested transaction in progress, if any.

        :return: an :class:`_asyncio.AsyncSessionTransaction` object, or
         ``None``.

        .. versionadded:: 1.4.18

        N)r3   get_nested_transactionrm   rn   ro   s     r9   rs   z#AsyncSession.get_nested_transaction  s2     !!88:*EEeLLrq   c                 B     | j                   j                  d|||d|S )a  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.orm import Session, sessionmaker

            # 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 = sessionmaker(
                class_=AsyncSession,
                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.

        )mapperclauser,   r.   )r3   get_bind)r5   ru   rv   r,   r6   s        r9   rw   zAsyncSession.get_bind  s4    T *t  )) 
&t
79
 	
rq   c                    K   t        | j                  j                  fi | d{   }t        j                  j                  |      S 7 #w)a  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"

        N)r   r3   
connectionr   AsyncConnectionrn   )r5   r6   sync_connections      r9   ry   zAsyncSession.connection  sQ     " !/((!
,.!
 
 %%@@
 	

s   $AA
$Ac                     t        |       S )a  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`.

        rm   r5   r6   s     r9   beginzAsyncSession.begin  s    * 't,,rq   c                     t        | d      S )a:  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`.

        T)nestedr}   r~   s     r9   begin_nestedzAsyncSession.begin_nested6  s     'tD99rq   c                 \   K   t        | j                  j                         d{   S 7 w)z-Rollback the current transaction in progress.N)r   r3   rollbackr5   s    r9   r   zAsyncSession.rollbackC  s#     #D$5$5$>$>????   #,*,c                 \   K   t        | j                  j                         d{   S 7 w)z+Commit the current transaction in progress.N)r   r3   commitr   s    r9   r   zAsyncSession.commitG  s#     #D$5$5$<$<====r   c                 ^   K   t        | j                  j                         d{    y7 w)aP  Close out the transactional resources and ORM objects used by this
        :class:`_asyncio.AsyncSession`.

        This expunges all ORM objects associated with this
        :class:`_asyncio.AsyncSession`, ends any transaction in progress and
        :term:`releases` any :class:`_asyncio.AsyncConnection` objects which
        this :class:`_asyncio.AsyncSession` itself has checked out from
        associated :class:`_asyncio.AsyncEngine` objects. The operation then
        leaves the :class:`_asyncio.AsyncSession` in a state which it may be
        used again.

        .. tip::

            The :meth:`_asyncio.AsyncSession.close` method **does not prevent
            the Session from being used again**. The
            :class:`_asyncio.AsyncSession` itself does not actually have a
            distinct "closed" state; it merely means the
            :class:`_asyncio.AsyncSession` will release all database
            connections and ORM objects.


        .. seealso::

            :ref:`session_closing` - detail on the semantics of
            :meth:`_asyncio.AsyncSession.close`

        N)r   r3   closer   s    r9   r   zAsyncSession.closeK  s"     8 T..44555s   #-+-c                 \   K   t        | j                  j                         d{   S 7 w)zClose this Session, using connection invalidation.

        For a complete description, see :meth:`_orm.Session.invalidate`.
        N)r   r3   
invalidater   s    r9   r   zAsyncSession.invalidatei  s%     
 $D$5$5$@$@AAAAr   c                 \   K   t        | j                  j                         d{   S 7 w)z2Close all :class:`_asyncio.AsyncSession` sessions.N)r   r3   	close_allr   s    r9   r   zAsyncSession.close_allp  s%      $D$5$5$?$?@@@@r   c                    K   | S wNr.   r   s    r9   
__aenter__zAsyncSession.__aenter__u  s     s   c                    K   t        j                         j                  | j                               }t        j                  |       d {    y 7 wr   )asyncioget_event_loopcreate_taskr   shield)r5   type_value	tracebacktasks        r9   	__aexit__zAsyncSession.__aexit__x  s7     %%'33DJJLAnnT"""s   A
AAAc                     t        |       S r   )_AsyncSessionContextManagerr   s    r9   _maker_context_managerz#AsyncSession._maker_context_manager|  s    *400rq   )NNN)NN)NFNN)TNr   )&__name__
__module____qualname____doc___is_asynciodispatchr:   r   r1   __annotations__r>   rD   r
   
EMPTY_DICTrM   rQ   rT   rY   r`   rb   rd   rg   rj   rl   rs   rw   ry   r   r   r   r   r   r   classmethodr   r   r   r   r.   rq   r9   r)   r)      s*   < KH$
L !  	 ?C
0G< // ?J //8 //  L 
> //+B // >H
G L
\
0-.:@>6<B A A#1rq   r)   c                       e Zd Zd Zd Zd Zy)r   c                     || _         y r   )async_session)r5   r   s     r9   r:   z$_AsyncSessionContextManager.__init__  s
    *rq   c                    K   | j                   j                         | _        | j                  j                          d {    | j                   S 7 wr   )r   r   rp   r   r   s    r9   r   z&_AsyncSessionContextManager.__aenter__  sC     ''--/
jj##%%%!!! 	&s   =AA Ac                     K    fd}t        j                         j                   |             }t        j                  |       d {    y 7 w)Nc                     K    j                   j                         d {     j                  j                         d {    y 7 *7 wr   )rp   r   r   )r5   r   r   r   s   r9   goz1_AsyncSessionContextManager.__aexit__.<locals>.go  sK     **&&ueY???$$..ueYGGG @Gs!   !AA$A	A
AA)r   r   r   r   )r5   r   r   r   r   r   s   ````  r9   r   z%_AsyncSessionContextManager.__aexit__  s<     	H %%'33BD9nnT"""s   A	AAAN)r   r   r   r:   r   r   r.   rq   r9   r   r     s    +"
#rq   r   c                   L    e Zd ZdZdZddZed        Zd Zd Z	d Z
ddZd	 Zy
)rm   a  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

    )sessionsync_transactionr   c                 .    || _         || _        d | _        y r   )r   r   r   )r5   r   r   s      r9   r:   z AsyncSessionTransaction.__init__  s     $rq   c                 ^    | j                         d uxr | j                         j                  S r   )_sync_transactionr!   r   s    r9   r!   z!AsyncSessionTransaction.is_active  s1     ""$D0 3&&(22	
rq   c                 R    | j                   s| j                          | j                   S r   )r   _raise_for_not_startedr   s    r9   r   z)AsyncSessionTransaction._sync_transaction  s#    $$'')$$$rq   c                 f   K   t        | j                         j                         d{    y7 w)z2Roll back this :class:`_asyncio.AsyncTransaction`.N)r   r   r   r   s    r9   r   z AsyncSessionTransaction.rollback  s#     T335>>???   '1/1c                 f   K   t        | j                         j                         d{    y7 w)z/Commit this :class:`_asyncio.AsyncTransaction`.N)r   r   r   r   s    r9   r   zAsyncSessionTransaction.commit  s%      T335<<===r   c                 ,  K   | j                  t        | j                  r | j                  j                  j
                  n| j                  j                  j                         d {         | _        |r| j                  j                          | S 7 +wr   )	r2   r   r   r   r3   r   r   r   	__enter__)r5   is_ctxmanagers     r9   startzAsyncSessionTransaction.start  sv      $ 4 4 ;; ))66\\..44 !
 !!++-s   A$B&B',Bc                 l   K   t        | j                         j                  |||       d {    y 7 wr   )r   r   __exit__)r5   r   r   r   s       r9   r   z!AsyncSessionTransaction.__aexit__  s0     ""$--ueY
 	
 	
s   *424N)F)r   r   r   r   	__slots__r:   propertyr!   r   r   r   r   r   r.   rq   r9   rm   rm     sA     :I%
 
 
%
@>


rq   rm   c                 4    t        |       }|t        |      S y)a  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

    N)r   r   )r?   r   s     r9   async_object_sessionr     s"    , X&GW%%rq   c                 0    t         j                  | d      S )a  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

    F)
regenerate)r)   rn   )r   s    r9   r   r     s     227u2MMrq   )r    r   r   r^   baser   r   r   r
   ormr   r   r   _instance_stateutil.concurrencyr   rJ   rL   r]   create_proxy_methodsr)   r   rm   r   r   _async_providerr.   rq   r9   <module>r      s       ! " '  !  + .%4%%'7&>? $$$$&6%=> $"N3	%:I	1? I	1;:I	1X# #$;
o/? ;
|:
N #0 rq   