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 ||¡}|rt ||d|¡}| r`t ||¡} n"t ||d|¡}| r`t ||¡} | rÐg} xd|D]\\}}||jkrŠd}n6|j|\}}|r°t ||¡df}nt ||¡df}|  |¡qpWx*| D]"\}}| || | |||||¡qÖWqÞWdS)zèestablish actions and dependencies related to a flush. These actions will operate on all relevant states individually. This occurs only if there are cycles in the 'aggregated' version of events. TFN)NN)rr-rr,r.r+ZdisabledZcyclesÚAssertionErrorrÚ base_mapperZmanagerrÚimplZget_all_pendingÚdictrrrZ ProcessStateZ DeleteStateZSaveUpdateStateÚstatesÚappendÚper_state_dependencies)rr)r;ÚisdeleteZchild_base_mapperr3r5r1r0Z child_actionsZchild_in_cyclesr2r4Zparent_in_cyclesr'Zsum_Z child_stateÚchildÚ child_actionÚdeletedZlistonlyÚ childisdeleterrr Úper_state_flush_actionsgsx            z+DependencyProcessor.per_state_flush_actionscCsdS)NFr)rÚ uowcommitr;rrr Úpresort_deletes×sz#DependencyProcessor.presort_deletescCsdS)NFr)rrDr;rrr Ú presort_savesÚsz!DependencyProcessor.presort_savescCsdS)Nr)rrDr;rrr Úprocess_deletesÝsz#DependencyProcessor.process_deletescCsdS)Nr)rrDr;rrr Ú process_savesàsz!DependencyProcessor.process_savescCsv|r |jrtj}n|jtkr$tj}ntj}xF|D]$}| ||j|¡}|r0|  ¡s0dSq0W|op|j j op|j |j kSdS)NT)rrrrrZPASSIVE_NO_FETCH_RELATEDrÚget_attribute_historyrÚemptyr Z_is_self_referentialrZmappers)rrDr;r>ÚpassiveÚsÚhistoryrrr Úprop_has_changesãs     z$DependencyProcessor.prop_has_changescCs–|jjr$|dkr$t d|jf¡‚nn|dk r’|jj||j ds’|jj|ddrtt d|j|j|jj|jdœ¡‚nt d|j|j|jjdœ¡‚dS)Nz-Can't flush None value found in collection %s)Zallow_subtypesTaEAttempting to flush an item of type %(x)s as a member of collection "%(y)s". Expected an object of type %(z)s or a polymorphic subclass of this type. If %(x)s is a subclass of %(z)s, configure mapper "%(zm)s" to load this subtype polymorphically, or set enable_typechecks=False to allow any subtype to be accepted for flush. )ÚxÚyÚzZzmz•Attempting to flush an item of type %(x)s as a member of collection "%(y)s". Expected an object of type %(z)s or a polymorphic subclass of this type.)rOrPrQ)r ÚuselistrZ FlushErrorrZ_canloadrÚclass_)rr'rrr Ú_verify_canloadùs$ z#DependencyProcessor._verify_canloadcCs tƒ‚dS)N)ÚNotImplementedError)rr'r?ÚassociationrowÚ clearkeysrDrrr Ú _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)rYÚlÚrrrr r[2sz4DependencyProcessor._post_update..)Zregister_post_updater r)rr'rDÚrelatedÚ is_m2o_deleterOrrr Ú _post_update.s   z DependencyProcessor._post_updatecCs tƒ‚dS)N)rU)rrDr'rrr Ú _pks_changed6sz DependencyProcessor._pks_changedcCsd|jj|jfS)Nz%s(%s))Ú __class__Ú__name__r )rrrr Ú__repr__9szDependencyProcessor.__repr__N)F)riÚ __module__Ú __qualname__r!Ú classmethodr$r&r*r6rCrErFrGrHrNrTrXrarfrgrjrrrr 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)rrrorr-rprq) rr)Ú save_parentÚ delete_parentr@r0r1r>rBrrrsrrr 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 ) rrwrrIrrrAr&Ú delete_orphanÚregister_objectÚ unchangedr )rrDr;Úshould_null_fksr'rMr?rrr rEª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_addedrvTÚadd)Z cancel_deleterxr Frw)r>rxr )r>z pk change)rxr )r_r`rryrrgrrrrrIrÚaddedrzr rqrAr&rÚcascade_iteratorr{)rrDr;r}r|r'Ú pks_changedrKrMr?ÚcÚmÚst_Údct_rrr rFÅ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)Nrvr}FT)rrr_r`rIrrrAr&rXrfrrwr{Ú difference)rrDr;r}r'rMr?rrr rGs,      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)NrvFT)rryrrIrrrrrXrrfrAr&rgr{)rrDr;r|r'rMr?rrr rH/s*        zOneToManyDP.process_savesc Csp|}|}| |¡|dks*|js.| |¡r.dS|rHt ||j|jj¡n$t ||j ||j|jj||j oh|¡dS)N) rTrÚ is_deletedrÚclearrr rÚpopulaterr) rr'r?rVrWrDrÚsourceÚdestrrr rXQs  zOneToManyDP._synchronizecCst |||j|jj¡S)N)rÚsource_modifiedrr r)rrDr'rrr rghszOneToManyDP._pks_changedN) rirkrlr/r=rErFrGrHrXrgrrrr rn=s)C>,"rnc@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)rrrorr-rprq) 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)rrrorr-rprq) rr)rtrur@r0r1r>rBrrrrr 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)NTrw)r>rxr )r>) rrwryrIrrÚsumZ non_deletedrzr rr€) rrDr;r'rMZtodeleter?Útr‚rƒr„r…rrr rEÖ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~)rxr FTrw)r>rxr )r>) rzr rryrIrrrAr&rr€) rrDr;r'rMr?r’r‚rƒr„r…rrr rFîs    zManyToOneDP.presort_savescCsr|jrn|jjsn|jdksnxT|D]L}| |ddd|¡|r|jr| ||j|j¡}|r|j|||  ¡ddqWdS)NrvT)re) rrryrrXrIrrrfr‘)rrDr;r'rMrrr rGs   zManyToOneDP.process_deletesc Cs†x€|D]x}| ||jtj¡}|r|jrLx>|jD]}| ||dd|d¡q.Wn|jrf| |ddd|d¡|jr| |||  ¡¡qWdS)NFr~Trw) rIrrrrrXrArrfr‘)rrDr;r'rMr?rrr rHs  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ˆrrrTr‰r)rr'r?rVrWrDrxrrr rX*s*    zManyToOneDP._synchronize)N) rirkrlr!r/r=rErFrGrHrXrrrr rns(:rc@sheZdZdZdd„Zdd„Zdd„Zdd „Zd d „Zd d „Z dd„Z dd„Z dd„Z dd„Z dd„ZdS)rŽa”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)rYr 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,rr8r+rprq)rr)r2r0rrr r6lsz*DetectKeySwitch.per_property_flush_actionscCsdS)Nr)rr)r;r>rrr rCqsz'DetectKeySwitch.per_state_flush_actionscCsdS)Nr)rrDr;rrr rEtszDetectKeySwitch.presort_deletescCs|js| ||¡dS)N)rÚ_process_key_switches)rr)r;rrr rFwszDetectKeySwitch.presort_savescCs"|s|jr| ||¡}t|ƒSdS)NF)rÚ_key_switchersÚbool)rr)r;r>Údrrr rN}s  z DetectKeySwitch.prop_has_changescCs dst‚dS)NF)r7)rrDr;rrr rG„szDetectKeySwitch.process_deletescCs|js t‚| ||¡dS)N)rr7r™)rrDr;rrr rH‡s zDetectKeySwitch.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_Úunionrgr~)rr)r;ZswitchedZ notswitchedZ allstatesrLrrr 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)rKéF)ršr“Z identity_mapZ all_statesÚ issubclassrSrr:r%rÚgetrrZPASSIVE_NO_RESULTr rRZinstance_staterzrrr‰rr) rZdeplistrDZ switchersr'Zdict_rdZ related_objZ related_staterrr r™s6      z%DetectKeySwitch._process_key_switchescCs t|jƒot |||j|jj¡S)N)r›rrrŒrr r)rrDr'rrr rgÂszDetectKeySwitch._pks_changedN)rirkrlÚ__doc__r*r6rCrErFrNrGrHršr™rgrrrr rŽSs  %rŽc@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)rprq)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)rprq) rr)rtrur@r0r1r>rBrrr r=ås z#ManyToManyDP.per_state_dependenciescCs*|js&x|D]}| ||j|j¡q WdS)N)rrIrr)rrDr;r'rrr rEþ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)NFTrw)r>rxr )r>)rrgrIrrrrryrrAr&rzr rr€) rrDr;r'rMr?r‚rƒr„r…rrr rF 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)NFrwc3s|]}|ˆfVqdS)Nr)rYr‚)r'rr r˜Ksz/ManyToManyDP.process_deletes..) rar`rIrrZ non_addedrXr<rqÚ _run_crud) rrDr;Úsecondary_deleteÚsecondary_insertÚsecondary_updateÚ processedÚtmprMr?rVr)r'r rG,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~rwc3s|]}|ˆfVqdS)Nr)rYr‚)r'rr r˜~sz-ManyToManyDP.process_saves..Úold_)rar`rrgrrrrIrrrXr<rArqr{rrr rrÚsecondary_synchronize_pairsr¥) rrDr;r¦r§r¨r©rªZneed_cascade_pksrKrMr?rVr)r'r rHTsn          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)rYr‚)rVrr r[¦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¯)rYr‚)rVrr r[ÀszRUPDATE statement on table '%s' expected to update %d row(s); Only %d were matched.)Z transactionÚ connectionrrrwr Úand_r‚ZexecuteZsupports_sane_multi_rowcountZrowcountÚlenrZStaleDataErrorÚ descriptionrqÚinsert)rrDr§r¨r¦r°Z statementÚresultr)rVr 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)rTr“r”rArr•r–r—r rZ populate_dictrrrr¬)rr'r?rVrWrDrxrrr rXÙs"  zManyToManyDP._synchronizecCst |||j|jj¡S)N)rrŒrr r)rrDr'rrr rgúszManyToManyDP._pks_changedN) rirkrlr/r=rErFrGrHr¥rXrgrrrr r¤Ès "(H=!r¤N)r£Úrrrrrr–Z interfacesrrr rr Úobjectr rnrrŽr¤r"rrrr Ú s4           &3fu;