U kfi@sdZddlmZddlmZddlmZddlmZddlmZddlmZdd l m Z dd l m Z dd l m Zd d l mZd d l m Z d dl mZerddlmZddlmZddlmZddlmZddlmZddlmZddZGdddZGdddZGdddeZGdddZ Gdd d ee Z!Gd!d"d"e Z"Gd#d$d$e Z#Gd%d&d&e Z$Gd'd(d(e Z%Gd)d*d*e Z&Gd+d,d,e Z'd-S).zThe internals for the unit of work system. The session's flush() process passes objects to a contextual object here, which assembles flush tasks based on mappers and their properties, organizes them in order of dependency, and executes. ) annotations)Any)Dict)Optional)Set) TYPE_CHECKING attributes)exc)util)event) topological)DependencyProcessor)MapperProperty)Mapper)Session)SessionTransaction) InstanceStatecs|jfdd}fdd}fdd}tj|d|ddd tj|d |dddd tj|d |dddd tj|d |dddd dS)z\Establish event listeners on object attributes which handle cascade-on-set/append. csh|dkr dS|j}|rd|jr&|d|jjj}t|}|jj rd|j krd| |sd| ||S)Nzcollection append) session_warn_on_events_flush_warningmanagermapper_propsr instance_state_cascade save_updatekey_contains_state_save_or_update_statestateitem initiatorkwsesspropZ item_staterI/opt/hc_python/lib64/python3.8/site-packages/sqlalchemy/orm/unitofwork.pyappend2s    z$track_cascade_events..appendcs|dkr dS|j}|jjj}|r>|jr>||jr8dnd|dk r|tjk r|tj k r|j j rt |}|j |r|r||jkr||nd|_dS)Nzcollection removezrelated attribute deleteT)rrrrrrZuselistr NEVER_SETPASSIVE_NO_RESULTr delete_orphanr _is_orphan_newexpungeZ_orphaned_outside_of_sessionr"r)r*r+removeIs.    z$track_cascade_events..removec s||kr |S|j}|r|jr&|d|jjj}|dk rlt|}|jj rl|j krl| |sl| ||dk r|tj k r|tjk r|jjrt|}||jkr|j|r|||S)Nzrelated attribute set)rrrrrrr rrrrr r!r-r.r/r1r0r2) r#ZnewvalueZoldvaluer%r&r'r(Znewvalue_stateZoldvalue_stater)r*r+set_ks<     z"track_cascade_events..set_Zappend_wo_mutationT)raw include_keyr,)r5retvalr6r3setN)rrlisten)Z descriptorr(r,r3r4r*r)r+track_cascade_events+sF  " $r:c @seZdZUded<ded<ded<ded<d ed <dd d d ZeddZddZddZddZ ddZ e j fddZ ddZddZd9d d!d!d!d"d#d!d$d%d&Zd'd(Zd)d*Zejd+d,Zd-d.Zd/d0Zd1d2Zd3d4d5d6Zd3d4d7d8ZdS):UOWTransactionrrrZ transactionzDict[str, Any]r z7util.defaultdict[Mapper[Any], Set[DependencyProcessor]]depsz6util.defaultdict[Mapper[Any], Set[InstanceState[Any]]]mappers)rcCsR||_i|_tt|_tt|_i|_i|_t|_ i|_ tdd|_ dS)NcSs ttfSN)r8r*r*r*r+z)UOWTransaction.__init__..) rr r defaultdictr8r<r=presort_actionspostsort_actions dependenciesstatespost_update_states)selfrr*r*r+__init__s  zUOWTransaction.__init__cCs t|jSr>)boolrErGr*r*r+has_workszUOWTransaction.has_workcCsD|jr@z||tjWn&tjk r>|j|gYdSXdS)zZReturn ``True`` if the given state is expired and was deleted previously. TF)ZexpiredZ _load_expiredr PASSIVE_OFForm_excZObjectDeletedErrorr_remove_newly_deletedrGr#r*r*r+was_already_deletedsz"UOWTransaction.was_already_deletedcCs||jko|j|dS)z[Return ``True`` if the given state is marked as deleted within this uowtransaction.rrErOr*r*r+ is_deletedszUOWTransaction.is_deletedcCs,||jkr|j|S||j|<}|SdSr>r )rGrZ callable_retr*r*r+memos  zUOWTransaction.memocCs |j|d}|df|j|<dS)z;Remove pending actions for a state from the uowtransaction.rTNrQ)rGr#isdeleter*r*r+remove_state_actionssz#UOWTransaction.remove_state_actionsc Csd||f}||jkr|j|\}}}|tj@s|tj@r|j|j}|||jtjtjBtjB}|rv|j rv| }n|}|||f|j|<nP|j|j}|||j|tjBtjB}|r|j r| }n|}|||f|j|<|S)zOFacade to attributes.get_state_history(), including caching of results.history) r ZSQL_OKrimplZ get_historydictrLZLOAD_AGAINST_COMMITTEDZNO_RAISEZ uses_objectsZas_state) rGr#rZpassiveZhashkeyrWZ state_historyZcached_passiverXr*r*r+get_attribute_historysH        z$UOWTransaction.get_attribute_historycCs|df|jkS)NT)rB)rG processorr*r*r+has_dep*szUOWTransaction.has_depcCs&||f}||jkr"t|||j|<dSr>)rB Preprocess)rGr[ fromparentrr*r*r+register_preprocessor-s z$UOWTransaction.register_preprocessorFNzInstanceState[Any]rIz Optional[str]zOptional[MapperProperty])r#rUlistonly cancel_delete operationr(returncCs|j|s8|js4|dk r4tdt|||fdS||jkr~|jj }||j kr^| ||j | |||f|j|<n|s|s|r|df|j|<dS)NzJObject of type %s not in session, %s operation along '%s' will not proceedFT) rr Zdeletedr warnorm_utilZstate_class_strrErrr=_per_mapper_flush_actionsadd)rGr#rUr`rarbr(rr*r*r+register_object2s"     zUOWTransaction.register_objectcCs0|jjj}|j|\}}||||dSr>)rr base_mapperrFrgupdate)rGr#Zpost_update_colsrrEcolsr*r*r+register_post_updateTs  z#UOWTransaction.register_post_updatecCsft||j}t||j}|j||f|jD]}||q.|jD]}|jrPqD|j }||qDdSr>) SaveUpdateAllri DeleteAllrDrgZ_dependency_processorsZper_property_preprocessorsZ relationshipsZviewonlyZ_dependency_processor)rGrZsavesZdeletesdepr(r*r*r+rfZs     z(UOWTransaction._per_mapper_flush_actionscCstddS)areturn a dynamic mapping of (Mapper, DependencyProcessor) to True or False, indicating if the DependencyProcessor operates on objects of that Mapper. The result is stored in the dictionary persistently once calculated. cSs |dj|dj|djkS)Nrr)rgetrr()tupr*r*r+r?sr@z0UOWTransaction._mapper_for_dep..)r Z PopulateDictrJr*r*r+_mapper_for_dephs zUOWTransaction._mapper_for_depcs|jfdd|DS)zmFilter the given list of InstanceStates to those relevant to the given DependencyProcessor. cs g|]}|jjfr|qSr*)rr.0sroZmapper_for_depr*r+ |sz8UOWTransaction.filter_states_for_dep..)rr)rGrorEr*rvr+filter_states_for_depvsz$UOWTransaction.filter_states_for_depccs>||f}|jjD](}|j|D]}|j||kr|VqqdSr>)riself_and_descendantsr=rE)rGrrUr`Zchecktupr#r*r*r+states_for_mapper_hierarchy~s  z*UOWTransaction.states_for_mapper_hierarchycsBd}tjD]}|rd}q|sq.qtjtj_}|r(fdd|D}tjD]}d|ks|dj s|dj s| |rj |qn|d|krj |||dD]}j ||dfqqn|d|krnj |||dD]}j |d|fq qndd jD |S) z}Generate the full, unsorted collection of PostSortRecs as well as dependency pairs for this UOWTransaction. FTcsi|]}|t|qSr*)r8per_state_flush_actions)rtrecrJr*r+ sz4UOWTransaction._generate_actions..NrrcSsh|]}|js|qSr*disabled)rtar*r*r+ sz3UOWTransaction._generate_actions..)listrBvaluesexecuterZ find_cyclesrDrCcyclesr issupersetr3rg difference)rGrSactionrconvertedgeror*rJr+_generate_actionssJ        z UOWTransaction._generate_actionsNone)rccCsx|}t|ddd}|jrVt|j|D]&}t|}|r,|}|||q8q,nt |j|D]}| |qddS)NcSs|jSr>)sort_key)r$r*r*r+r?r@z(UOWTransaction.execute..r)) rsortedrrZsort_as_subsetsrDr8popexecute_aggregatesortr)rGrCZsubsetr4nr|r*r*r+rs  zUOWTransaction.executecCsV|js dSt|j}dd|jD}||}|rB|j||rR|j|dS)zMark processed objects as clean / deleted after a successful flush(). This method is called within the flush() method after the execute() method has succeeded and the transaction has been committed. NcSsh|]\}\}}|r|qSr*r*)rtrurUr`r*r*r+rs z8UOWTransaction.finalize_flush_changes..)rEr8itemsrrrNZ_register_persistent)rGrEZisdelotherr*r*r+finalize_flush_changess   z%UOWTransaction.finalize_flush_changes)FFFNN)__name__ __module__ __qualname____annotations__rHpropertyrKrPrRrTrVr ZPASSIVE_NO_INITIALIZErZr\r_rhrlrfr Zmemoized_propertyrrrxrzrrrr*r*r*r+r;s> -   5" 4r;c@seZdZdZddZdS)IterateMappersMixinr*cs2jr$tfddjjjDSjjjSdS)Nc3s"|]}j|jfr|VqdSr>)rrdependency_processor)rtmrGuowr*r+ sz/IterateMappersMixin._mappers..)r^iterrparentryrrr*rr+_mapperss zIterateMappersMixin._mappersN)rrr __slots__rr*r*r*r+rsrc@s eZdZdZddZddZdS)r])rr^ processedsetup_flush_actionscCs||_||_t|_d|_dSNF)rr^r8rr)rGrr^r*r*r+rHszPreprocess.__init__cCst}t}||D]H}|j||jD]0}|j|\}}|s,|rR||q,||q,q|r~|j|||j ||r|j |||j ||s|r|j s|j ||ds|j ||dr|j |d|_ dSdSdSNTF)r8rr=rrrErgrZpresort_deletesrjZ presort_savesrZprop_has_changesZper_property_flush_actions)rGrZ delete_statesZ save_statesrr#rUr`r*r*r+rsB    zPreprocess.executeN)rrrrrHrr*r*r*r+r]sr]c@s eZdZdZddZddZdS) PostSortRecr~cGs@|f|}||jkr|j|St||j|<}d|_|SdSr)rCobject__new__r)clsrargsrrSr*r*r+r-s    zPostSortRec.__new__cCs||dSr>)r)rGrrecsr*r*r+r6szPostSortRec.execute_aggregateN)rrrrrrr*r*r*r+r*s rc@s8eZdZdZddZddZddZdd Zd d Zd S) ProcessAll)rrUr^rcCs:||_d|jj|f|_||_||_|j|jj|dS)Nr)rrrUr^r<rrirg)rGrrrUr^r*r*r+rH=szProcessAll.__init__cCs2||}|jr |j||n|j||dSr>) _elementsrUrprocess_deletes process_saves)rGrrEr*r*r+rJs zProcessAll.executecCstgSr>)rrr*r*r+r{Qsz"ProcessAll.per_state_flush_actionscCsd|jj|j|jfS)Nz%s(%s, isdelete=%s)) __class__rrrUrJr*r*r+__repr__Xs zProcessAll.__repr__ccsF||D]6}|j|D]&}|j|\}}||jkr|s|Vqq dSr>)rr=rErU)rGrrr#rUr`r*r*r+r_s zProcessAll._elementsN) rrrrrHrr{rrr*r*r*r+r:s  rc@s*eZdZdZddZedddZdS) PostUpdateAll)rrUrcCs||_||_d|j|f|_dS)Nr)rrU _sort_keyr)rGrrrUr*r*r+rHjszPostUpdateAll.__init__sqlalchemy.orm.persistencecsBtjj}jj\}}fdd|D}|j||dS)Ncs$g|]}j|djkr|qSr)rErUrsrr*r+rwssz)PostUpdateAll.execute..)r preloadedorm_persistencerFrZ post_update)rGr persistencerErkr*rr+roszPostUpdateAll.executeN)rrrrrHr preload_modulerr*r*r*r+rgsrc@s:eZdZdZddZedddZddZd d Z d S) rmrrcCs$||_d|jf|_||jks tdS)NrmrrrriAssertionErrorrGrrr*r*r+rH{s zSaveUpdateAll.__init__rcCs$tjj|j||jdd|dSr)r rrsave_objrrzrr*r*r+rs zSaveUpdateAll.executec cst||jdd}|jj}t||}|D]$}t||}|j||f|Vq*|j|jD]}| ||}| ||dq\dSr) rrzrrirnSaveUpdateStaterDrgr<rxr{) rGrrEriZ delete_allr#rrostates_for_propr*r*r+r{s   z%SaveUpdateAll.per_state_flush_actionscCsd|jj|jfSNz%s(%s)rrrrJr*r*r+rszSaveUpdateAll.__repr__N rrrrrHr rrr{rr*r*r*r+rmxs  rmc@s:eZdZdZddZedddZddZd d Z d S) rnrcCs$||_d|jf|_||jks tdS)Nrnrrr*r*r+rHs zDeleteAll.__init__rcCs$tjj|j||jdd|dSr)r rr delete_objrrzrr*r*r+rs zDeleteAll.executec cst||jdd}|jj}t||}|D]$}t||}|j||f|Vq*|j|jD]}| ||}| ||dq\dSr) rrzrrirm DeleteStaterDrgr<rxr{) rGrrEriZsave_allr#rrorr*r*r+r{s   z!DeleteAll.per_state_flush_actionscCsd|jj|jfSrrrJr*r*r+rszDeleteAll.__repr__Nrr*r*r*r+rns  rnc@s(eZdZdZddZddZddZdS) ProcessState)rrUr#rcCs"||_d|jf|_||_||_dSNr)rrrUr#)rGrrrUr#r*r*r+rHs zProcessState.__init__csj|j|j|jfdd|D}|||jgdd|D}rZ||n ||dS)Ncs.g|]&}|jkr|jkr|jkr|qSr*)rrrUrtrcls_rrUr*r+rws    z2ProcessState.execute_aggregate..cSsg|] }|jqSr*r#rr*r*r+rws)rrrUdifference_updater#rr)rGrrour_recsrEr*rr+rs zProcessState.execute_aggregatecCs d|jj|jt|j|jfS)Nz%s(%s, %s, delete=%s))rrrre state_strr#rUrJr*r*r+rs  zProcessState.__repr__N)rrrrrHrrr*r*r*r+rsrc@s2eZdZdZddZedddZddZd S) rr#rrcCs"||_|jj|_d|jjf|_dSrr#rrirrrGrr#r*r*r+rHs zSaveUpdateState.__init__rcsVtjj}|j|jfdd|D}||||jgdd|D|dS)Ncs$g|]}|jkr|jkr|qSr*rrrrrr*r+rws z5SaveUpdateState.execute_aggregate..cSsg|] }|jqSr*rrr*r*r+rws)r rrrrrrr#)rGrrrrr*rr+rs  z!SaveUpdateState.execute_aggregatecCsd|jjt|jfSrrrrerr#rJr*r*r+rs zSaveUpdateState.__repr__N rrrrrHr rrrr*r*r*r+rs  rc@s2eZdZdZddZedddZddZd S) rrcCs"||_|jj|_d|jjf|_dS)Nrrrr*r*r+rHs zDeleteState.__init__rcshtjj}|j|jfdd|D}|||jgdd|D}|fdd|DdS)Ncs$g|]}|jkr|jkr|qSr*rrrr*r+rws z1DeleteState.execute_aggregate..cSsg|] }|jqSr*rrr*r*r+rwscsg|]}j|dr|qSrrQrs)rr*r+rws)r rrrrrr#r)rGrrrrrEr*)rrrr+r s  zDeleteState.execute_aggregatecCsd|jjt|jfSrrrJr*r*r+rs zDeleteState.__repr__Nrr*r*r*r+rs  rN)(__doc__ __future__rtypingrrrrrr r rMr rerr dependencyrZ interfacesrrrrrrr#rr:r;rr]rrrrmrnrrrr*r*r*r+ sB                  rO2-%%$