U kfX&@sdZddlmZddlmZddlmZddlmZddlmZddlmZddlm Z dd lm Z dd lm Z dd lm Z dd lm Z d dlmZd dlmZd dlmZd dlmZd dlmZd dlmZd dlmZd dlmZd dlmZd dlmZd dlmZddlmZddl m!Z!e rd dlm"Z"d dl#m$Z$d dlm%Z%d dlm&Z&d dl'm(Z(d d lm)Z)dd!l*m+Z+dd"l,m-Z-e d#ed$Z.Gd%d&d&ee.Z/Gd'd(d(eZ0ej1j2d)d*Gd+d,d,eZ3Gd-d.d.ee.Z4Gd/d0d0e4e.ee.Z5d1d2d3d4d5Z6d6S)7zDynamic collection API. Dynamic collections act like Query() objects for read operations and support basic add/delete mutation. .. legacy:: the "dynamic" loader is a legacy feature, superseded by the "write_only" loader. ) annotations)Any)Iterable)Iterator)List)Optional)Tuple)Type) TYPE_CHECKING)TypeVar)Union) attributes)exc) relationships)util) PassiveFlag)Query)object_session)AbstractCollectionWriter)WriteOnlyAttributeImpl)WriteOnlyHistory)WriteOnlyLoader)result)QueryableAttribute)Mapper)_RelationshipOrderByArg)Session) InstanceState) AliasedClass) _Dispatch) ColumnElement_T)boundc@s$eZdZd dddddddd ZdS) DynamicCollectionHistoryNDynamicAttributeImplInstanceState[_T]rz&Optional[DynamicCollectionHistory[_T]]None)attrstatepassiveapply_toreturncCs`|r8t||d}t||_|j|_|j|_d|_n$t|_t|_t|_d|_dS)NFT) AppenderQuery autoflushrZOrderedIdentitySetZunchanged_items added_itemsZ deleted_itemsZ_reconcile_collection)selfr)r*r+r,Zcollr2F/opt/hc_python/lib64/python3.8/site-packages/sqlalchemy/orm/dynamic.py__init__>s    z!DynamicCollectionHistory.__init__)N)__name__ __module__ __qualname__r4r2r2r2r3r%=sr%c @s@eZdZUdZeeZded<dddddd d d d d ddZdS)r&TzType[AppenderMixin[Any]] query_classNz#Union[Type[Any], AliasedClass[Any]]strz"_Dispatch[QueryableAttribute[Any]]z Mapper[_T]rz!Optional[Type[AppenderMixin[_T]]]rr()class_keydispatch target_mapperorder_byr8kwr-cKsZtjj|||d|f|||_|r,t||_|s8t|_nt| krL||_n t ||_dSN) rZ AttributeImplr4r=tupler>r.r8 AppenderMixinmromixin_user_query)r1r:r;r<r=r>r8r?r2r2r3r4Ws"   zDynamicAttributeImpl.__init__)N) r5r6r7Z_supports_dynamic_iterationr%rZcollection_history_cls__annotations__r4r2r2r2r3r&Rs  r&Zdynamic)Zlazyc@seZdZeZdS) DynaLoaderN)r5r6r7r&Z impl_classr2r2r2r3rFosrFcseZdZUdZdZded<ded<ddd d fd d Zed dddZej dd dddZddddZ e rddddZ dddddZ ddd d!Zd4d d"d#d$d%Zd&d d'd(d)Zd*d d+d,d-Zd&d d'd.d/Zd*d d+d0d1Zd*d d+d2d3ZZS)5rBzTA mixin that expects to be mixing in a Query class with AbstractAppender. NzOptional[Type[Query[_T]]]r8zTuple[ColumnElement[Any], ...]_order_by_clausesr&r'r()r)r*r-cs"t||jdt||dSr@)rr4r=super)r1r)r* __class__r2r3r4~s zAppenderMixin.__init__zOptional[Session])r-cCsBt|j}|dk r*|jr*|j|kr*|t|js:dS|SdSr@)rinstancer/flushorm_utilZ has_identityr1sessr2r2r3sessions   zAppenderMixin.sessionr)rPr-cCs ||_dSr@)rO)r1rPr2r2r3rPsz1Union[result.ScalarResult[_T], result.Result[_T]]cCs|j}|dkrpt|j}|jr4tdt|t j t |j j jgt|j t|jtjjddS||SdS)NzInstance %s is detached, dynamic relationship cannot return a correct result. This warning will become a DetachedInstanceError in a future release.T)Z_source_supports_scalars)rPrinstance_staterKZdetachedrwarnrMZ state_strrZIteratorResultZSimpleResultMetaDatar)r:r5iter_get_collection_historyrPASSIVE_NO_INITIALIZEr0Zscalars _generate_iter)r1rOr*r2r2r3rWs(   zAppenderMixin._iterz Iterator[_T]cCsdSr@r2)r1r2r2r3__iter__zAppenderMixin.__iter__rzUnion[_T, List[_T]])indexr-cCs@|j}|dkr,|jt|jtj|S| | |SdSr@) rPr)rTrrQrKrrUZindexedrV __getitem__)r1rZrOr2r2r3r[s zAppenderMixin.__getitem__intcCs>|j}|dkr,t|jt|jtjj S| | SdSr@) rPlenr)rTrrQrKrrUr0rVcountrNr2r2r3r^s zAppenderMixin.countz Query[_T])rOr-cCs~|j}|dkr:t|}|dkr:tdt||jjf|jrT|j|jj |d}n| |jj }|j |_ |j |_ |j |_ |S)NzParent instance %s is not bound to a Session, and no contextual session is established; lazy load operation of attribute '%s' cannot proceed)rP)rKrorm_excZDetachedInstanceErrorrMZ instance_strr)r;r8r=queryZ_where_criteriaZ _from_objrG)r1rOrKr`r2r2r3rVs zAppenderMixin._generatez Iterable[_T])iteratorr-cCs||dS)a~Add an iterable of items to this :class:`_orm.AppenderQuery`. The given items will be persisted to the database in terms of the parent instance's collection on the next flush. This method is provided to assist in delivering forwards-compatibility with the :class:`_orm.WriteOnlyCollection` collection class. .. versionadded:: 2.0 NZ _add_all_implr1rar2r2r3add_alls zAppenderMixin.add_allr#)itemr-cCs||gdS)apAdd an item to this :class:`_orm.AppenderQuery`. The given item will be persisted to the database in terms of the parent instance's collection on the next flush. This method is provided to assist in delivering forwards-compatibility with the :class:`_orm.WriteOnlyCollection` collection class. .. versionadded:: 2.0 Nrbr1rer2r2r3adds zAppenderMixin.addcCs||dS)zAdd an iterable of items to this :class:`_orm.AppenderQuery`. The given items will be persisted to the database in terms of the parent instance's collection on the next flush. Nrbrcr2r2r3extendszAppenderMixin.extendcCs||gdS)zAppend an item to this :class:`_orm.AppenderQuery`. The given item will be persisted to the database in terms of the parent instance's collection on the next flush. Nrbrfr2r2r3append szAppenderMixin.appendcCs||dS)zRemove an item from this :class:`_orm.AppenderQuery`. The given item will be removed from the parent instance's collection on the next flush. N)Z _remove_implrfr2r2r3removeszAppenderMixin.remove)N)r5r6r7__doc__r8rEr4propertyrPsetterrWr rXr[r^rVrdrgrhrirj __classcell__r2r2rIr3rBts(       rBc@seZdZdZdS)r.zA dynamic query that supports basic collection storage operations. Methods on :class:`.AppenderQuery` include all methods of :class:`_orm.Query`, plus additional methods used for collection persistence. N)r5r6r7rkr2r2r2r3r.sr.rztype[AppenderMixin[Any]])clsr-cCsd|j}t|t|fd|iS)zAReturn a new class with AppenderQuery functionality layered over.ZAppenderr8)r5typerB)ronamer2r2r3rD)s rDN)7rk __future__rtypingrrrrrrr r r r rrr_rrrMbaserr`rrPrZ writeonlyrrrrZenginerrZmapperrrrr*rr eventr!Z sql.elementsr"r#r%r&ZRelationshipPropertyZ strategy_forrFrBr.rDr2r2r2r3 sT                                  +