B ÃÌ4]ܵã@sìdZddlmZddlmZddlmZddlmZddlmZddlm Z ddlm Z dd lm Z d dlmZ d d lm Z d dlmZGd d „d eƒZGdd„deƒZGdd„deƒZGdd„deƒZGdd„deƒZe ee ee eiZdS)zRelationship dependencies. é)Ú attributes)Úexc)Úsync)Ú unitofwork)Úutil)Ú MANYTOMANY)Ú MANYTOONE)Ú ONETOMANYé)Úsqlc@sšeZdZdd„Zedd„ƒZdd„Zdd„Zd d „Zd d „Z d d„Z dd„Z dd„Z dd„Z dd„Zdd„Zdd„Zdd„Zd%dd„Zd d!„Zd"d#„Zd$S)&ÚDependencyProcessorcCs¢||_|j|_|j|_|j|_|j|_|j|_|j|_|j|_|j|_|j |_ |jr^t j |_ nt j |_ |jrvt j |_nt j |_|j|_|jjsžt d|j¡‚dS)Nz|Can't build a DependencyProcessor for relationship %s. No target attributes to populate between parent and child are present)ÚpropÚcascadeÚmapperÚparentÚ secondaryÚ directionÚ post_updateÚpassive_deletesÚpassive_updatesÚenable_typechecksrÚPASSIVE_NO_INITIALIZEÚ_passive_delete_flagÚ PASSIVE_OFFÚ_passive_update_flagÚkeyÚsynchronize_pairsÚsa_excZ ArgumentError)Úselfr ©rúL/opt/alt/python37/lib64/python3.7/site-packages/sqlalchemy/orm/dependency.pyÚ__init__s*  zDependencyProcessor.__init__cCst|j|ƒS)N)Ú_direction_to_processorr)Úclsr rrr Úfrom_relationship6sz%DependencyProcessor.from_relationshipcCs|jj |j¡ |¡S)z¤return True if the given object instance has a parent, according to the ``InstrumentedAttribute`` handled by this ``DependencyProcessor``. )rZ class_managerÚget_implrÚ hasparent)rÚstaterrr r&:szDependencyProcessor.hasparentcCs| |d¡dS)z•establish actions and dependencies related to a flush. These actions will operate on all relevant states in the aggregate. TN)Úregister_preprocessor)rÚuowrrr Úper_property_preprocessorsBsz.DependencyProcessor.per_property_preprocessorsc Cszt ||dd¡}t ||dd¡}t ||jj¡}t ||jj¡}t ||jj¡}t ||jj¡}| |||||||¡dS)NFT)rÚ ProcessAllÚ SaveUpdateAllrÚprimary_base_mapperrÚ DeleteAllÚper_property_dependencies)rr)Ú after_saveÚ before_deleteÚ parent_savesÚ child_savesÚparent_deletesÚ child_deletesrrr Úper_property_flush_actionsKs$    z.DependencyProcessor.per_property_flush_actionsc Csô|jj}t ||¡}t ||¡}|rÚassociationrowÚ clearkeysrCrrr Ú _synchronize"sz DependencyProcessor._synchronizecCs>|jjs dStt|jgdd„|jjDƒƒƒ}| d|ft¡S)NcSsg|] }|j‘qSr)r)Ú.0Úprrr ú *szCDependencyProcessor._get_reversed_processed_set..Z reverse_key)r Ú_reverse_propertyÚtupleÚsortedrÚmemoÚset)rr)Z process_keyrrr Ú_get_reversed_processed_set%s  z/DependencyProcessor._get_reversed_processed_setFcCs:x4|D],}|r|dk r| |dd„|jjDƒ¡PqWdS)NcSsg|] \}}|‘qSrr)rXÚlÚrrrr rZ2sz4DependencyProcessor._post_update..)Zregister_post_updater r)rr'rCÚrelatedÚ is_m2o_deleterNrrr Ú _post_update.s   z DependencyProcessor._post_updatecCs tƒ‚dS)N)rT)rrCr'rrr Ú _pks_changed6sz DependencyProcessor._pks_changedcCsd|jj|jfS)Nz%s(%s))Ú __class__Ú__name__r )rrrr Ú__repr__9szDependencyProcessor.__repr__N)F)rhÚ __module__Ú __qualname__r!Ú classmethodr$r&r*r6rBrDrErFrGrMrSrWr`rerfrirrrr r s"  p) r c@sLeZdZdd„Zdd„Zdd„Zdd„Zd d „Zd d „Zd d„Z dd„Z dS)Ú OneToManyDPc Cs–|jr\t ||jjd¡}t ||jjd¡} |j ||f||f||f|| f| |f| |fg¡n6|j ||f||f||f||f||f||f||fg¡dS)NFT)rrÚ PostUpdateAllrr-Ú dependenciesÚupdate) rr)r2r3r4r5r0r1Úchild_post_updatesÚchild_pre_updatesrrr r/>s( z%OneToManyDP.per_property_dependenciesc Csä|jr¤t ||jjd¡} t ||jjd¡} |sl|rL|j ||f|| fg¡q¢|j ||f||f|| fg¡qà|rŠ|j || f| |fg¡qà|j || f| |fg¡n<|sÈ|j ||f||f||fg¡n|j ||f||fg¡dS)NFT)rrrnrr-rorp) rr)Ú save_parentÚ delete_parentr?r0r1r=rArqrrrrr r<gs8 z"OneToManyDP.per_state_dependenciescCs´|jj o|jdk }x˜|D]}| ||j|j¡}|rxF|jD]<}|dk r>| |¡dkr>|jjrp|j |ddq>|  |¡q>W|rx(|j D]}|dk rŠ|j |d|j dqŠWqWdS)NÚallFT)r=Údelete)Ú operationr ) rrvrrHrrr@r&Ú delete_orphanÚregister_objectÚ unchangedr )rrCr:Úshould_null_fksr'rLr>rrr rDªs   zOneToManyDP.presort_deletesc Csn| d|ft¡}|jj o$|jdk }x@|D]6}| ||¡}|rJ|jrRtj}ntj }|  ||j |¡}|r*x*|j D] } | dk rv|j | dd|jdqvW| |j ¡x‚|jD]x} |jjsÔ|rÒ|j | dd|jdq®| | ¡dkr®|j | dd|jdx.|j d| ¡D]\} } } } |j | dd qWq®W|r.|r.x2|jD](} | dk r:|j | d|jd |jd q:Wq.WdS) NÚchildren_addedruTÚadd)Z cancel_deleterwr Frv)r=rwr )r=z pk change)rwr )r^r_rrxrrfrrrrrHrÚaddedryr rpr@r&rÚcascade_iteratorrz)rrCr:r|r{r'Ú pks_changedrJrLr>ÚcÚmÚst_Údct_rrr rEÅsZ           zOneToManyDP.presort_savesc Csú|js|jdksö| d|ft¡}xÔ|D]Ì}| ||j|j¡}|r&xR|jD]H}|dk rH| |¡dkrH|  ||dd|d¡|jrH|rH|  |||g¡qHW|js¢|j j s&xNt|j ƒ |¡D]:}|dk r´|  ||dd|d¡|jr´|r´|  |||g¡q´Wq&WdS)Nrur|FT)rrr^r_rHrrr@r&rWrerrvrzÚ difference)rrCr:r|r'rLr>rrr rFs,      zOneToManyDP.process_deletesc Csê|jj o|jdk }xÎ|D]Æ}| ||jtj¡}|rx@|jD]6}| ||dd|d¡|dk r>|j r>|  |||g¡q>Wx8|j D].}|r€|jjs€|  |¡s€| ||dd|d¡q€W|  ||¡rx"|jD]}| ||dd|d¡qÆWqWdS)NruFT)rrxrrHrrrr~rWrrer@r&rfrz)rrCr:r{r'rLr>rrr rG/s*        zOneToManyDP.process_savesc Csp|}|}| |¡|dks*|js.| |¡r.dS|rHt ||j|jj¡n$t ||j ||j|jj||j oh|¡dS)N) rSrÚ is_deletedrÚclearrr rÚpopulaterr) rr'r>rUrVrCr€ÚsourceÚdestrrr rWQs  zOneToManyDP._synchronizecCst |||j|jj¡S)N)rÚsource_modifiedrr r)rrCr'rrr rfhszOneToManyDP._pks_changedN) rhrjrkr/r<rDrErFrGrWrfrrrr rm=s)C>,"rmc@sNeZdZdd„Zdd„Zdd„Zdd„Zd d „Zd d „Zd d„Z ddd„Z dS)Ú ManyToOneDPcCs2t ||¡x |jjD]}|j t|ƒ¡qWdS)N)r r!rZself_and_descendantsZ_dependency_processorsr;ÚDetectKeySwitch)rr rrrr r!os zManyToOneDP.__init__c CsŠ|jrbt ||jjd¡}t ||jjd¡} |j ||f||f||f|| f|| f| |f| |fg¡n$|j ||f||f||f||fg¡dS)NFT)rrrnrr-rorp) rr)r2r3r4r5r0r1Úparent_post_updatesÚparent_pre_updatesrrr r/ts$ z%ManyToOneDP.per_property_dependenciesc CsÜ|jrŒ|sZt ||jjd¡} |r:|j || f| |fg¡qŠ|j ||f||f|| fg¡qØt ||jjd¡} |j || f| |f| |fg¡nL|sÂ|s®|j ||f||fg¡qØ|j ||fg¡n|rØ|j ||fg¡dS)NFT)rrrnrr-rorp) rr)rsrtr?r0r1r=rArŽrrrr r<œs2 z"ManyToOneDP.per_state_dependenciesc Cs°|jjs|jjr¬xš|D]’}| ||j|j¡}|r|jjrB| ¡}n| ¡}x\|D]T}|dkr^qP|j|dd|j d|j   d|¡}x"|D]\}} } } |j| ddq†WqPWqWdS)NTrv)r=rwr )r=) rrvrxrHrrÚsumZ non_deletedryr rr) rrCr:r'rLZtodeleter>Útrr‚rƒr„rrr rDÖs&    zManyToOneDP.presort_deletesc Cs¦x |D]˜}|j|d|jd|jjr| ||j|j¡}|rxb|jD]X}| |¡dkrB|j|dd|jd|j   d|¡}x"|D]\}}} } |j| ddq|WqBWqWdS)Nr})rwr FTrv)r=rwr )r=) ryr rrxrHrrr@r&rr) rrCr:r'rLr>r‘rr‚rƒr„rrr rEîs    zManyToOneDP.presort_savescCsr|jrn|jjsn|jdksnxT|D]L}| |ddd|¡|r|jr| ||j|j¡}|r|j|||  ¡ddqWdS)NruT)rd) rrrxrrWrHrrrer)rrCr:r'rLrrr rFs   zManyToOneDP.process_deletesc Cs†x€|D]x}| ||jtj¡}|r|jrLx>|jD]}| ||dd|d¡q.Wn|jrf| |ddd|d¡|jr| |||  ¡¡qWdS)NFr}Trv) rHrrrr~rWr@rrer)rrCr:r'rLr>rrr rGs  zManyToOneDP.process_savesNc Cs¦|dks|js| |¡rdS|dk rX|dk rX|j |¡sXt dt |¡||jf¡dS|sd|dkrzt   ||j |jj ¡n(|  |¡t  ||j||j |jj |d¡dS)NzGObject of type %s not in session, %s operation along '%s' won't proceedF)rr†ÚsessionÚ_contains_staterÚwarnÚ mapperutilÚstate_class_strr rr‡rrrSrˆr)rr'r>rUrVrCrwrrr rW*s*    zManyToOneDP._synchronize)N) rhrjrkr!r/r<rDrErFrGrWrrrr rŒns(:rŒc@sheZdZdZdd„Zdd„Zdd„Zdd „Zd d „Zd d „Z dd„Z dd„Z dd„Z dd„Z dd„ZdS)ra”For many-to-one relationships with no one-to-many backref, searches for parents through the unit of work when a primary key has changed and updates them. Theoretically, this approach could be expanded to support transparent deletion of objects referenced via many-to-one as well, although the current attribute system doesn't do enough bookkeeping for this to be efficient. cCs<|jjr,|jrdSddd„|jjDƒkr,dS| |d¡dS)NFcss|] }|jVqdS)N)r)rXr rrr ú esz=DetectKeySwitch.per_property_preprocessors..)r r[rr()rr)rrr r*_sz*DetectKeySwitch.per_property_preprocessorscCs6t ||jj¡}t ||dd¡}|j ||fg¡dS)NF)rr,rr7r+rorp)rr)r2r0rrr r6lsz*DetectKeySwitch.per_property_flush_actionscCsdS)Nr)rr)r:r=rrr rBqsz'DetectKeySwitch.per_state_flush_actionscCsdS)Nr)rrCr:rrr rDtszDetectKeySwitch.presort_deletescCs|js| ||¡dS)N)rÚ_process_key_switches)rr)r:rrr rEwszDetectKeySwitch.presort_savescCs"|s|jr| ||¡}t|ƒSdS)NF)rÚ_key_switchersÚbool)rr)r:r=Údrrr rM}s  z DetectKeySwitch.prop_has_changescCsdS)Nr)rrCr:rrr rF„szDetectKeySwitch.process_deletescCs| ||¡dS)N)r˜)rrCr:rrr rG‡szDetectKeySwitch.process_savescCs^| d|fdd„¡\}}| |¡}x6|D].}||kr(| ||¡rL| |¡q(| |¡q(W|S)NZ pk_switcherscSs tƒtƒfS)N)r_rrrr Ú‘óz0DetectKeySwitch._key_switchers..)r^Úunionrfr})rr)r:ZswitchedZ notswitchedZ allstatesrKrrr r™s    zDetectKeySwitch._key_switchersc CsÌ| ||¡}|rÈx¶|jj ¡D]¦}t|j|jjƒs4q|j}| |j ¡j |||j d}|t j k r|dk r|jjr~|stq|d}n|}t  |¡}||kr| |d|j¡t ||j||j|jj||j¡qWdS)N)rJéF)r™r’Z identity_mapZ all_statesÚ issubclassrRrr9r%rÚgetrrZPASSIVE_NO_RESULTr rQZinstance_stateryrrrˆrr) rZdeplistrCZ switchersr'Zdict_rcZ related_objZ related_staterrr r˜s6      z%DetectKeySwitch._process_key_switchescCs t|jƒot |||j|jj¡S)N)ršrrr‹rr r)rrCr'rrr rfÂszDetectKeySwitch._pks_changedN)rhrjrkÚ__doc__r*r6rBrDrErMrFrGr™r˜rfrrrr rSs  %rc@sTeZdZdd„Zdd„Zdd„Zdd„Zd d „Zd d „Zd d„Z dd„Z dd„Z dS)Ú ManyToManyDPc Cs:|j ||f||f||f||f||f||f||fg¡dS)N)rorp)rr)r2r3r4r5r0r1rrr r/És z&ManyToManyDP.per_property_dependenciesc CsX|s<|r"|j ||f||fg¡qT|j ||f||fg¡n|j ||f||fg¡dS)N)rorp) rr)rsrtr?r0r1r=rArrr r<ås z#ManyToManyDP.per_state_dependenciescCs*|js&x|D]}| ||j|j¡q WdS)N)rrHrr)rrCr:r'rrr rDþs zManyToManyDP.presort_deletesc CsÆ|js2x*|D]"}| ||¡r | ||jtj¡}q W|jjs>dSx‚|D]z}| ||jtj¡}|rDx^|j D]T}|  |¡dkrf|j |dd|j dx,|j  d|¡D]\}}}} |j |ddqœWqfWqDWdS)NFTrv)r=rwr )r=)rrfrHrrrrrxrr@r&ryr rr) rrCr:r'rLr>rr‚rƒr„rrr rE s*     zManyToManyDP.presort_savesc sÖg}g}g}| |¡}tƒ}x’|D]Љ| ˆ|j|j¡}|r"xR| ¡D]F} | dksF|dk rhˆ| f|krhqFi} | ˆ| | d|d¡s‚qF| | ¡qFW| ‡fdd„| ¡Dƒ¡q"W|dk rÂ| |¡|  ||||¡dS)NFrvc3s|]}|ˆfVqdS)Nr)rXr)r'rr r—Ksz/ManyToManyDP.process_deletes..) r`r_rHrrZ non_addedrWr;rpÚ _run_crud) rrCr:Úsecondary_deleteÚsecondary_insertÚsecondary_updateÚ processedÚtmprLr>rUr)r'r rF,s8    zManyToManyDP.process_deletesc s˜g}g}g}| |¡}tƒ}xP|D]F‰|j o<| |ˆ¡}|rJtj} ntj} | ˆ|j| ¡} | r$xH| j D]>} |dk r†ˆ| f|kr†qli} |  ˆ| | d|d¡s ql|  | ¡qlWxH| j D]>} |dk rЈ| f|krÐq¶i} |  ˆ| | d|d¡sêq¶|  | ¡q¶W|  ‡fdd„| j | j Dƒ¡|r$xN| jD]D} i} t  ˆ|j| d|jj¡t  | |j| d|jj¡|  | ¡q$Wq$W|dk r„|  |¡| ||||¡dS)NFr}rvc3s|]}|ˆfVqdS)Nr)rXr)r'rr r—~sz-ManyToManyDP.process_saves..Úold_)r`r_rrfrrrrHrr~rWr;r@rprzrrr rrÚsecondary_synchronize_pairsr¤) rrCr:r¥r¦r§r¨r©Zneed_cascade_pksrJrLr>rUr)r'r rGTsn          zManyToManyDP.process_savescs|j |j¡}|r~|d‰|j tj‡fdd„|jjDƒŽ¡}| ||¡}|  ¡r~|j t |ƒkr~t   d|jjt |ƒ|j f¡‚|rî|d‰|j tj‡fdd„|jjDƒŽ¡}| ||¡}|  ¡rî|j t |ƒkrît   d|jjt |ƒ|j f¡‚|r |j ¡}| ||¡dS)NrŸcs,g|]$}|jˆkr|tj|j|jdk‘qS))Útype_)rr Ú bindparamÚtype)rXr)rUrr rZ¦sz*ManyToManyDP._run_crud..zRDELETE statement on table '%s' expected to delete %d row(s); Only %d were matched.cs0g|](}|jˆkr|tjd|j|jdk‘qS)rª)r¬)rr r­r®)rXr)rUrr rZÀszRUPDATE statement on table '%s' expected to update %d row(s); Only %d were matched.)Z transactionÚ connectionrrrvr Úand_rZexecuteZsupports_sane_multi_rowcountZrowcountÚlenrZStaleDataErrorÚ descriptionrpÚinsert)rrCr¦r§r¥r¯Z statementÚresultr)rUr r¤œs@       zManyToManyDP._run_crudcCs€| |¡|dkrdS|dk rP|j |¡sP|jsLt dt |¡||jf¡dSt   ||j ||jj ¡t   ||j ||jj¡dS)NFzGObject of type %s not in session, %s operation along '%s' won't proceedT)rSr’r“r@rr”r•r–r rZ populate_dictrrrr«)rr'r>rUrVrCrwrrr rWÙs"  zManyToManyDP._synchronizecCst |||j|jj¡S)N)rr‹rr r)rrCr'rrr rfúszManyToManyDP._pks_changedN) rhrjrkr/r<rDrErFrGr¤rWrfrrrr r£Ès "(H=!r£N)r¢Úrrrrrr•Z interfacesrrr rr Úobjectr rmrŒrr£r"rrrr Ú s4           &3fu;