o znh#@spdZddlmZddlmZddlmZddlmZddgZGdddeZ Gd d d e Z Gd ddeZ d S) aHorizontal 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. )inspect)util)Query)SessionShardedSession ShardedQuerycsTeZdZfddZddZddZddZ dfd d Zdfd d ZZ S)rcs4tt|j|i||jj|_|jj|_d|_dSN)superr__init__session id_chooser query_chooser _shard_id)selfargskwargs __class__J/usr/local/lib/python3.10/dist-packages/sqlalchemy/ext/horizontal_shard.pyr s   zShardedQuery.__init__cCs|}||_|S)zreturn 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. )_cloner)rshard_idqrrr set_shard"szShardedQuery.set_shardcs`fdd}jdur|jSjdur|jSg}D] }|||q"t|S)Ncs:|jd<_j|djj}|S)Nr)mapperr) attributesidentity_token_connection_from_session _bind_mapperexecute statement_params instances)rresultcontextrrriter_for_shard.s  z;ShardedQuery._execute_and_instances..iter_for_shard)rrr extenditer)rr%r&partialrrr$r_execute_and_instances-s    z#ShardedQuery._execute_and_instancescsbfdd}jdur|jSd}g}D]}||}||j7}||qt||S)Ncs$j|dd}|j}|S)NT)rrclauseclose_with_result)rrr!)rconnr#rrstmtrrexec_for_shardCsz2ShardedQuery._execute_crud..exec_for_shard)rr rowcountappend ShardedResult)rr/rr0r2resultsrr#rr.r _execute_crudBs    zShardedQuery._execute_crudNc  s|durtt|j||fd|i|S|j|}|r ||}|||D]}tt|j||fd|i|}|dur?|Sq&dS)zoverride the default Query._identity_lookup method so that we search for a given non-token primary key identity across all possible identity tokens (e.g. shard ids). Nr)r r_identity_lookupr query_set_lazyload_fromr ) rrprimary_key_identityrlazy_loaded_fromkwrrobjrrrr7Ys0    zShardedQuery._identity_lookupcs<fdd}|durjdurj}ttj|||dS)zOverride the default Query._get_impl() method so that we emit a query to the DB for each possible identity token, if we don't have one already. csXjdur |St|}|D]}|}||}|dur)|SqdSr)rrto_listr r)r8r:identrro db_load_fnrrr _db_load_fns     z+ShardedQuery._get_impl.._db_load_fnN)r)rr r _get_impl)rr:rBrrCrrArrD{s  zShardedQuery._get_impl)NNr) __name__ __module__ __qualname__r rr*r6r7rD __classcell__rrrrrs  "c@s(eZdZdZdZddZeddZdS)r4aA value object that represents multiple :class:`.ResultProxy` objects. This is used by the :meth:`.ShardedQuery._execute_crud` hook to return an object that takes the place of the single :class:`.ResultProxy`. Attribute include ``result_proxies``, which is a sequence of the actual :class:`.ResultProxy` objects, as well as ``aggregate_rowcount`` or ``rowcount``, which is the sum of all the individual rowcount values. .. versionadded:: 1.3 result_proxiesaggregate_rowcountcCs||_||_dSrrI)rrJrKrrrr s zShardedResult.__init__cCs|jSr)rK)rrrrr2szShardedResult.rowcountN)rErFrG__doc__ __slots__r propertyr2rrrrr4s  r4csHeZdZdeffdd ZddZd ddZ d dd Zd d ZZ S) rNc sdtt|jdd|i|||_||_||_i|_|j|_|dur.|D] }| |||q#dSdS)aConstruct 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 query_chooser: For a given Query, 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. :param shards: A dictionary of string shard names to :class:`~sqlalchemy.engine.Engine` objects. query_clsNr) r rr shard_chooserr r _ShardedSession__binds connectionconnection_callable bind_shard)rrPr r shardsrOrkrrrr szShardedSession.__init__cKsb|durt|}|jr|jd}|dusJ|S|jr|jS|j||fi|}|dur/||_|S)Nr)rkeyrrP)rrinstancer<statetokenrrrr_choose_shard_and_assigns  z'ShardedSession._choose_shard_and_assigncKsJ|dur |||}|jdur|jj||dS|j|||djdi|S)N)r)rrXr)r[ transactionrRget_bind_contextual_connect)rrrXrrrrrrRs  zShardedSession.connectioncKs"|dur |j|||d}|j|S)N)r+)r[rQ)rrrrXr+r<rrrr]s  zShardedSession.get_bindcCs||j|<dSr)rQ)rrbindrrrrTszShardedSession.bind_shard)NNN) rErFrGrr r[rRr]rTrHrrrrrs(   N) rLrr orm.queryr orm.sessionr__all__robjectr4rrrrrs