U al@sdZddlmZddlmZddlmZddlmZddlmZddlmZdd Z d d Z Gd d d e Z Gddde Z Gddde ZGddde ZGddde eZGdddeZGdddeZGdddeZGdddeZGdddeZGd d!d!eZd"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.  attributes)exc)util)event) topologicalcCstjd|jj|fdddS)NaH"%s" object is being merged into a Session along the backref cascade path for relationship "%s"; in SQLAlchemy 2.0, this reverse cascade will not take place. Set cascade_backrefs to False in either the relationship() or backref() function for the 2.0 behavior; or to set globally for the whole Session, set the future=True flagZs9r1)code)rZwarn_deprecated_20class___name__)stateproprZC:\Users\vtejo\AppData\Local\Temp\pip-unpacked-wheel-nyjtotrf\sqlalchemy\orm\unitofwork.py_warn_for_cascade_backrefss  rcs||jfdd}fdd}fdd}tj|d|dd tj|d |ddd tj|d |ddd tj|d |ddd dS)z\Establish event listeners on object attributes which handle cascade-on-set/append. cs|dkr dS|j}|r|jr&|d|jjj}t|}|jj r|j rR|j r\|j kr| |s|j krzt|||||S)Nzcollection append)session_warn_on_events_flush_warningmanagermapper_propsrinstance_state_cascade save_updatecascade_backrefsfuturekey_contains_stater_save_or_update_stater item initiatorsessr Z item_staterrrappend+s,     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_sessionrr#rrremoveGs.    z$track_cascade_events..removecs||kr |S|j}|r|jr&|d|jjj}|dk rt|}|jj r|j rZ|j rd|j kr| |s|j krt|||||dk r|tjk r|tjk r|jjrt|}||jkr|j|r|||S)Nzrelated attribute set)rrrrrrrrrrrrrrrrr%r&r'r)r(r*)r ZnewvalueZoldvaluer!r"r Znewvalue_stateZoldvalue_stater#rrset_isH       z"track_cascade_events..set_Zappend_wo_mutationT)rawr$)r-retvalr+setN)rrlisten)Z descriptorr r$r+r,rr#rtrack_cascade_events$s  " *r1c@seZdZddZeddZddZddZd d Zd d Z e j fd dZ ddZ ddZd'ddZddZddZejddZddZdd Zd!d"Zd#d$Zd%d&ZdS)(UOWTransactioncCsR||_i|_tt|_tt|_i|_i|_t|_ i|_ tdd|_ dS)NcSs ttfSN)r/rrrrz)UOWTransaction.__init__..) rrr defaultdictr/depsmapperspresort_actionspostsort_actions dependenciesstatespost_update_states)selfrrrr__init__s  zUOWTransaction.__init__cCs t|jSr3)boolr<r>rrrhas_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_deletedr>r rrrwas_already_deletedsz"UOWTransaction.was_already_deletedcCs||jko|j|dS)z[Return ``True`` if the given state is marked as deleted within this uowtransaction.r<rFrrr is_deletedszUOWTransaction.is_deletedcCs,||jkr|j|S||j|<}|SdSr3r)r>rZ callable_retrrrmemos  zUOWTransaction.memocCs |j|d}|df|j|<dS)z;Remove pending actions for a state from the uowtransaction.rHTNrI)r>r isdeleterrrremove_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) rZSQL_OKrimplZ get_historydictrCZLOAD_AGAINST_COMMITTEDZNO_RAISEZ uses_objectsZas_state) r>r rZpassiveZhashkeyrOZ state_historyZcached_passiverPrrrget_attribute_historysH        z$UOWTransaction.get_attribute_historycCs|df|jkS)NT)r9)r> processorrrrhas_dep szUOWTransaction.has_depcCs&||f}||jkr"t|||j|<dSr3)r9 Preprocess)r>rS fromparentrrrrregister_preprocessor#s z$UOWTransaction.register_preprocessorFNcCs|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) rrZdeletedrwarnorm_utilZstate_class_strr<rrr8_per_mapper_flush_actionsadd)r>r rMlistonlyZ cancel_deleteZ operationr rrrrregister_object(s"     zUOWTransaction.register_objectcCs0|jjj}|j|\}}||||dSr3)rr base_mapperr=r[update)r>r Zpost_update_colsrr<colsrrrregister_post_updateJs  z#UOWTransaction.register_post_updatecCsft||j}t||j}|j||f|jD]}||q.|jD]}|jrPqD|j }||qDdSr3) SaveUpdateAllr^ DeleteAllr;r[Z_dependency_processorsZper_property_preprocessorsZ relationshipsZviewonlyZ_dependency_processor)r>rZsavesZdeletesdepr rrrrZPs     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)NrHr)rgetrr )tuprrrr4ir5z0UOWTransaction._mapper_for_dep..)rZ PopulateDictrArrr_mapper_for_dep^s zUOWTransaction._mapper_for_depcs|jfdd|DS)zmFilter the given list of InstanceStates to those relevant to the given DependencyProcessor. cs g|]}|jjfr|qSr)rr.0srdZmapper_for_deprr rsz8UOWTransaction.filter_states_for_dep..)rg)r>rdr<rrkrfilter_states_for_deplsz$UOWTransaction.filter_states_for_depccs>||f}|jjD](}|j|D]}|j||kr|VqqdSr3)r^self_and_descendantsr8r<)r>rrMr\Zchecktupr rrrstates_for_mapper_hierarchyts  z*UOWTransaction.states_for_mapper_hierarchycsJd}tjD]}|rd}q|sq.qtjtj_}|r,t fdd|D}tjD]}d|ks|dj s|dj s| |rj |qr|d|krj |||dD]}j ||dfqqr|d|krrj |||dD]}j |d|fqqrtdd jD|S) z}Generate the full, unsorted collection of PostSortRecs as well as dependency pairs for this UOWTransaction. FTc3s |]}|t|fVqdSr3)r/per_state_flush_actions)rirecrArr sz3UOWTransaction._generate_actions..NrHrcSsg|]}|js|qSrdisabled)riarrrrlsz4UOWTransaction._generate_actions..)listr9valuesexecuterZ find_cyclesr;r:cyclesrQrt issupersetr+r[r/ difference)r>rKactionryconvertZedgerdrrAr_generate_actions{sJ        z UOWTransaction._generate_actionscCsx|}t|ddd}|jrVt|j|D]&}t|}|r,|}|||q8q,nt |j|D]}| |qddS)NcSs|jSr3)sort_key)r rrrr4r5z(UOWTransaction.execute..r#) r~sortedryrZsort_as_subsetsr;r/popexecute_aggregatesortrx)r>r:Zsubsetr,nrqrrrrxs  zUOWTransaction.executecCsZ|js dSt|j}tdd|jD}||}|rF|j||rV|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. Ncss|]\}\}}|r|VqdSr3r)rirjrMr\rrrrrs z8UOWTransaction.finalize_flush_changes..)r<r/itemsr{rrEZ_register_persistent)r>r<Zisdelotherrrrfinalize_flush_changess   z%UOWTransaction.finalize_flush_changes)FFFNN)r __module__ __qualname__r?propertyrBrGrJrLrNrZPASSIVE_NO_INITIALIZErRrTrWr]rarZrZmemoized_propertyrgrmror~rxrrrrrr2s4-   5 " 4r2c@seZdZddZdS)IterateMappersMixincs2jr$tfddjjjDSjjjSdS)Nc3s"|]}j|jfr|VqdSr3)rgdependency_processor)rimr>uowrrrrsz/IterateMappersMixin._mappers..)rViterrparentrnrrrrr_mapperss zIterateMappersMixin._mappersN)r rrrrrrrrsrc@s eZdZdZddZddZdS)rU)rrV processedsetup_flush_actionscCs||_||_t|_d|_dSNF)rrVr/rr)r>rrVrrrr?szPreprocess.__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)r/rr8r{rr<r[rZpresort_deletesr_Z presort_savesrZprop_has_changesZper_property_flush_actions)r>rZ delete_statesZ save_statesrr rMr\rrrrxsB    zPreprocess.executeN)r rr __slots__r?rxrrrrrUsrUc@s eZdZdZddZddZdS) PostSortRecrscGs@|f|}||jkr|j|St||j|<}d|_|SdSr)r:object__new__rt)clsrargsrrKrrrr!s    zPostSortRec.__new__cCs||dSr3)rx)r>rrecsrrrr*szPostSortRec.execute_aggregateN)r rrrrrrrrrrs rc@s8eZdZdZddZddZddZdd Zd d Zd S) ProcessAll)rrMrVrcCs:||_d|jj|f|_||_||_|j|jj|dS)Nr)rrrMrVr7rr^r[)r>rrrMrVrrrr?1szProcessAll.__init__cCs2||}|jr |j||n|j||dSr3) _elementsrMrprocess_deletes process_saves)r>rr<rrrrx>s zProcessAll.executecCstgSr3)rrrrrrpEsz"ProcessAll.per_state_flush_actionscCsd|jj|j|jfS)Nz%s(%s, isdelete=%s)) __class__r rrMrArrr__repr__Ls zProcessAll.__repr__ccsF||D]6}|j|D]&}|j|\}}||jkr|s|Vqq dSr3)rr8r<rM)r>rrr rMr\rrrrSs zProcessAll._elementsN) r rrrr?rxrprrrrrrr.s  rc@s*eZdZdZddZedddZdS) PostUpdateAll)rrMrcCs||_||_d|j|f|_dS)Nr)rrM _sort_keyr)r>rrrMrrrr?^szPostUpdateAll.__init__sqlalchemy.orm.persistencecsBtjj}jj\}}fdd|D}|j||dS)Ncs$g|]}j|djkr|qSrH)r<rMrhrrrrlgsz)PostUpdateAll.execute..)r preloadedorm_persistencer=rZ post_update)r>r persistencer<r`rrrrxcszPostUpdateAll.executeN)r rrrr?rpreload_modulerxrrrrr[src@s:eZdZdZddZedddZddZd d Z d S) rbrrcCs$||_d|jf|_||jks tdS)Nrbrrrr^AssertionErrorr>rrrrrr?os zSaveUpdateAll.__init__rcCs$tjj|j||jdd|dSr)rrrsave_objrrorrrrrxts zSaveUpdateAll.executec cst||jdd}|jj}t||}|D]$}t||}|j||f|Vq*|j|jD]}| ||}| ||dq\dSr) rvrorr^rcSaveUpdateStater;r[r7rmrp) r>rr<r^Z delete_allr r|rdstates_for_proprrrrp|s   z%SaveUpdateAll.per_state_flush_actionscCsd|jj|jfSNz%s(%s)rr rrArrrrszSaveUpdateAll.__repr__N r rrrr?rrrxrprrrrrrbls  rbc@s:eZdZdZddZedddZddZd d Z d S) rcrcCs$||_d|jf|_||jks tdS)Nrcrrrrrr?s zDeleteAll.__init__rcCs$tjj|j||jdd|dSr)rrr delete_objrrorrrrrxs zDeleteAll.executec cst||jdd}|jj}t||}|D]$}t||}|j||f|Vq*|j|jD]}| ||}| ||dq\dSr) rvrorr^rb DeleteStater;r[r7rmrp) r>rr<r^Zsave_allr r|rdrrrrrps   z!DeleteAll.per_state_flush_actionscCsd|jj|jfSrrrArrrrszDeleteAll.__repr__Nrrrrrrcs  rcc@s(eZdZdZddZddZddZdS) ProcessState)rrMr rcCs"||_d|jf|_||_||_dSNr)rrrMr )r>rrrMr rrrr?s zProcessState.__init__csj|j|j|jfdd|D}|||jgdd|D}rZ||n ||dS)Ncs.g|]&}|jkr|jkr|jkr|qSr)rrrMrircls_rrMrrrls    z2ProcessState.execute_aggregate..cSsg|] }|jqSrr rrrrrls)rrrMdifference_updater rr)r>rrour_recsr<rrrrs zProcessState.execute_aggregatecCs d|jj|jt|j|jfS)Nz%s(%s, %s, delete=%s))rr rrY state_strr rMrArrrrs  zProcessState.__repr__N)r rrrr?rrrrrrrsrc@s2eZdZdZddZedddZddZd S) rr rrcCs"||_|jj|_d|jjf|_dSrr rr^rrr>rr rrrr?s zSaveUpdateState.__init__rcsVtjj}|j|jfdd|D}||||jgdd|D|dS)Ncs$g|]}|jkr|jkr|qSrrrrrrrrrls z5SaveUpdateState.execute_aggregate..cSsg|] }|jqSrrrrrrrls)rrrrrrrr )r>rrrrrrrrs  z!SaveUpdateState.execute_aggregatecCsd|jjt|jfSrrr rYrr rArrrrs zSaveUpdateState.__repr__N r rrrr?rrrrrrrrrs  rc@s2eZdZdZddZedddZddZd S) rrcCs"||_|jj|_d|jjf|_dS)Nrrrrrrr?s zDeleteState.__init__rcshtjj}|j|jfdd|D}|||jgdd|D}|fdd|DdS)Ncs$g|]}|jkr|jkr|qSrrrrrrrls z1DeleteState.execute_aggregate..cSsg|] }|jqSrrrrrrrlscsg|]}j|dr|qSrrIrh)rrrrl s)rrrrrrr r)r>rrrrr<r)rrrrrs  zDeleteState.execute_aggregatecCsd|jjt|jfSrrrArrrr s zDeleteState.__repr__Nrrrrrrs  rN)__doc__rrrDrrYrrrr1rr2rrUrrrrbrcrrrrrrrs*       uI 2-%%$