o
    =a"                     @   s   d 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	gZ
G d
d	 d	eZG dd de	Zdd ZdS )a  Horizontal sharding support.

Defines a rudimental 'horizontal sharding' system which allows a Session to
distribute queries and persistence operations across multiple databases.

For a usage example, see the :ref:`examples_sharding` example included in
the source distribution.

   )event)exc)inspect)util)Query)SessionShardedSessionShardedQueryc                       s$   e Zd Z fddZdd Z  ZS )r	   c                    s>   t t| j|i | | jj| _| jj| _| jj| _d | _d S N)superr	   __init__session
id_chooserquery_chooserexecute_chooser	_shard_id)selfargskwargs	__class__ U/var/www/html/gps/gps/lib/python3.10/site-packages/sqlalchemy/ext/horizontal_shard.pyr      s
   



zShardedQuery.__init__c                 C   s   | j |dS )a  Return a new query, limited to a single shard ID.

        All subsequent operations with the returned query will
        be against the single shard regardless of other state.

        The shard_id can be passed for a 2.0 style execution to the
        bind_arguments dictionary of :meth:`.Session.execute`::

            results = session.execute(
                stmt,
                bind_arguments={"shard_id": "my_shard"}
            )

        )_sa_shard_id)execution_options)r   shard_idr   r   r   	set_shard$   s   zShardedQuery.set_shard)__name__
__module____qualname__r   r   __classcell__r   r   r   r   r	      s    c                       s^   e Zd Zddef fdd	Z		d fdd	Zdd Z	ddd	Z	dd
dZdd Z	  Z
S )r   Nc                    s   | dd tt| jdd|i| tj| dtdd || _|| _ r;t	
dd |r1td	 fd
d}|| _n|| _ | _i | _|durU|D ]}| |||  qJdS dS )a  Construct a ShardedSession.

        :param shard_chooser: A callable which, passed a Mapper, a mapped
          instance, and possibly a SQL clause, returns a shard ID.  This id
          may be based off of the attributes present within the object, or on
          some round-robin scheme. If the scheme is based on a selection, it
          should set whatever state on the instance to mark it in the future as
          participating in that shard.

        :param id_chooser: A callable, passed a query and a tuple of identity
          values, which should return a list of shard ids where the ID might
          reside.  The databases will be queried in the order of this listing.

        :param execute_chooser: For a given :class:`.ORMExecuteState`,
          returns the list of shard_ids
          where the query should be issued.  Results from all shards returned
          will be combined together into a single listing.

          .. versionchanged:: 1.4  The ``execute_chooser`` parameter
             supersedes the ``query_chooser`` parameter.

        :param shards: A dictionary of string shard names
          to :class:`~sqlalchemy.engine.Engine` objects.

        r   N	query_clsdo_orm_executeT)retvalzMThe ``query_choser`` parameter is deprecated; please use ``execute_chooser``.z1.4z>Can't pass query_chooser and execute_chooser at the same time.c                    s
    | j S r
   )	statementorm_contextr   r   r   r   n   s   
z0ShardedSession.__init__.<locals>.execute_chooserr   )popr   r   r   r   listenexecute_and_instancesshard_chooserr   r   warn_deprecatedr   ArgumentErrorr   r   _ShardedSession__binds
bind_shard)r   r+   r   r   shardsr!   r   kr   r'   r   r   7   s4   "zShardedSession.__init__c           	         s   |durt t| j||fd|i|S | |}|r||}| ||D ]}t t| j||f||d|}|dur?|  S q%dS )a_  override the default :meth:`.Session._identity_lookup` method so
        that we search for a given non-token primary key identity across all
        possible identity tokens (e.g. shard ids).

        .. versionchanged:: 1.4  Moved :meth:`.Session._identity_lookup` from
           the :class:`_query.Query` object to the :class:`.Session`.

        Nidentity_token)r2   lazy_loaded_from)r   r   _identity_lookupquery_set_lazyload_fromr   )	r   mapperprimary_key_identityr2   r3   kwqr   objr   r   r   r4   z   s4   



zShardedSession._identity_lookupc                 K   sb   |d urt |}|jr|jd }|d usJ |S |jr|jS | j||fi |}|d ur/||_|S )Nr   )r   keyr2   r+   )r   r7   instancer9   statetokenr   r   r   r   _choose_shard_and_assign   s   
z'ShardedSession._choose_shard_and_assignc                 K   sJ   |du r
|  ||}|  r|  j||dS | j|||djdi |S )zaProvide a :class:`_engine.Connection` to use in the unit of work
        flush process.

        N)r   )r   r=   r   )r@   in_transactionget_transaction
connectionget_bindconnect)r   r7   r=   r   r   r   r   r   connection_callable   s   z"ShardedSession.connection_callablec                 K   s"   |d u r| j |||d}| j| S )N)clause)r@   r.   )r   r7   r   r=   rG   r9   r   r   r   rD      s
   
zShardedSession.get_bindc                 C   s   || j |< d S r
   )r.   )r   r   bindr   r   r   r/      s   zShardedSession.bind_shard)NN)NNN)NNNN)r   r   r   r	   r   r4   r@   rF   rD   r/   r    r   r   r   r   r   6   s    G)

	c           	         s    j r j }}d }n js jrd } j }}nd  } }} j} fdd}|r3|jd ur3|j}nd jv r> jd }nd jv rI jd }nd }|d urU||||S g }|	 D ]}||||}|
| q\|d j|dd   S )Nc                    sf   t  j}t  j}| |d<  jr|d| i7 }||d< n js" jr,|d| i7 }||d<  j||dS )Nr   _refresh_identity_token_sa_orm_load_options_sa_orm_update_options)bind_argumentsr   )dictlocal_execution_optionsrL   	is_select	is_update	is_deleteinvoke_statement)r   load_optionsupdate_optionsr   rL   r%   r   r   iter_for_shard   s   


z-execute_and_instances.<locals>.iter_for_shardr   r          )rO   rS   rP   rQ   update_delete_optionsr   rI   r   rL   r   appendmerge)	r&   rS   active_optionsrT   r   rU   r   partialresult_r   r%   r   r*      s.   


r*   N)__doc__ r   r   r   r   	orm.queryr   orm.sessionr   __all__r	   r   r*   r   r   r   r   <module>   s   
 