U a@sdZddlmZddlmZddlmZddlmZddlmZddlm Z ddlm Z dd lm Z d dlmZ d d lm Z d dlmZGd d d eZGdddeZGdddeZGdddeZGdddeZe ee ee eiZdS)zRelationship dependencies. ) attributes)exc)sync) unitofwork)util) MANYTOMANY) MANYTOONE) ONETOMANY)sqlc@seZdZddZeddZddZddZd d Zd d Z d dZ ddZ ddZ ddZ ddZddZddZddZd%ddZd d!Zd"d#Zd$S)&DependencyProcessorcCs||_|j|_|j|_|j|_|j|_|j|_|j|_|j|_|j|_|j |_ |jr^t j |_ nt j |_ |jrvt j |_nt j |_d|jj|jf|_|j|_|jjstd|jdS)Nz%s_%sz|Can't build a DependencyProcessor for relationship %s. No target attributes to populate between parent and child are present)propcascademapperparent secondary direction post_updatepassive_deletespassive_updatesenable_typechecksrPASSIVE_NO_INITIALIZE_passive_delete_flag PASSIVE_OFF_passive_update_flag _sort_keykeysort_keysynchronize_pairssa_exc ArgumentError)selfr r"ZC:\Users\vtejo\AppData\Local\Temp\pip-unpacked-wheel-nyjtotrf\sqlalchemy\orm\dependency.py__init__s0  zDependencyProcessor.__init__cCst|j|SN)_direction_to_processorr)clsr r"r"r#from_relationship7sz%DependencyProcessor.from_relationshipcCs|jj|j|S)zreturn True if the given object instance has a parent, according to the ``InstrumentedAttribute`` handled by this ``DependencyProcessor``. )rZ class_managerget_implr hasparentr!stater"r"r#r*;szDependencyProcessor.hasparentcCs||ddS)zestablish actions and dependencies related to a flush. These actions will operate on all relevant states in the aggregate. TN)register_preprocessorr!uowr"r"r#per_property_preprocessorsCsz.DependencyProcessor.per_property_preprocessorsc Cszt||dd}t||dd}t||jj}t||jj}t||jj}t||jj}||||||||dSNFT)r ProcessAll SaveUpdateAllrprimary_base_mapperr DeleteAllper_property_dependencies)r!r/ after_save before_delete parent_saves child_savesparent_deletes child_deletesr"r"r#per_property_flush_actionsLs6z.DependencyProcessor.per_property_flush_actionsc Cs|jj}t||}t||}|r|jjs dStt|jgdd|jjD}|d|ftS)NcSsg|] }|jqSr")r).0pr"r"r# 0szCDependencyProcessor._get_reversed_processed_set..Z reverse_key)r _reverse_propertytuplesortedrmemoset)r!r/Z process_keyr"r"r#_get_reversed_processed_set+s z/DependencyProcessor._get_reversed_processed_setFcCs8|D].}|r|dk r||dd|jjDq4qdS)NcSsg|] \}}|qSr"r")relrr"r"r#rg8sz4DependencyProcessor._post_update..)Zregister_post_updater r)r!r,rOrelated is_m2o_deleterZr"r"r# _post_update4s z DependencyProcessor._post_updatecCs tdSr%r`r!rOr,r"r"r# _pks_changed<sz DependencyProcessor._pks_changedcCsd|jj|jfS)Nz%s(%s)) __class____name__r )r!r"r"r#__repr__?szDependencyProcessor.__repr__N)F)rv __module__ __qualname__r$ classmethodr(r*r0r=rLrPrQrRrSrYr_rdrmrrrtrwr"r"r"r#r s$  p) r c@sLeZdZddZddZddZddZd d Zd d Zd dZ ddZ dS) OneToManyDPc Cs|jr\t||jjd}t||jjd} |j||f||f||f|| f| |f| |fgn6|j||f||f||f||f||f||f||fgdSr1rr PostUpdateAllrr4 dependenciesupdate) r!r/r9r:r;r<r7r8child_post_updateschild_pre_updatesr"r"r#r6Ds<  z%OneToManyDP.per_property_dependenciesc Cs|jrt||jjd} t||jjd} |sl|rL|j||f|| fgq|j||f||f|| fgq|r|j|| f| |fgq|j|| f| |fgn<|s|j||f||f||fgn|j||f||fgdSr1r|) r!r/ save_parent delete_parentrIr7r8rGrKrrr"r"r#rFmsZ z"OneToManyDP.per_state_dependenciescCs|jj o|jdk }|D]}|||j|j}|r|jD]<}|dk r:||dkr:|jjrl|j |ddq:| |q:|r|j D]}|dk r|j |d|j dqqdS)NallFTrGdelete operationr ) rrrrTrrrJr* delete_orphanregister_object unchangedr r!rOrDshould_null_fksr,rXrHr"r"r#rPs,   zOneToManyDP.presort_deletesc CsV|d|ft}|jj o$|jdk }|D]$}|||}|rF|jrNtj}ntj }| ||j |}|r|j D] } | dk rp|j | dd|jdqp||j |jD]r} |jjs|r|j | dd|jdq|| dkr|j | dd|jd|jd| D]\} } } } |j | dd qq|r*|r*|jD](} | dk r&|j | d|jd |jd q&q*dS) Nchildren_addedrTadd)Z cancel_deleterr FrrGrr rz pk changer)rkrlrrrrtrrrrrTraddedrr rrJr*rcascade_iteratorr)r!rOrDrrr, pks_changedrVrXrHcmst_dct_r"r"r#rQsh          zOneToManyDP.presort_savesc Cs|js|jdks|d|ft}|D]}|||j|j}|r$|jD]H}|dk rD||dkrD| ||dd|d|jrD|rD| |||gqD|js|j j s$t|j |D]:}|dk r| ||dd|d|jr|r| |||gqq$dS)NrrFT)rrrkrlrTrrrJr*rdrrrrr difference)r!rOrDrr,rXrHr"r"r#rR sV     zOneToManyDP.process_deletesc Cs|jj o|jdk }|D]}|||jtj}|r|jD]6}|||dd|d|dk r:|j r:| |||gq:|j D].}|rx|jjsx| |sx|||dd|dqx| ||r|jD]}|||dd|dqqdS)NrFT)rrrrTrrrrrdrrrrJr*rtrrr"r"r#rS5s\      zOneToManyDP.process_savesc Csp|}|}|||dks*|js.||r.dS|rHt||j|jjn$t||j ||j|jj||j oh|dSr%) r_r is_deletedrclearrr rpopulaterr) r!r,rHrbrcrOrsourcedestr"r"r#rdWs( zOneToManyDP._synchronizecCst|||j|jjSr%rsource_modifiedrr rrsr"r"r#rtns zOneToManyDP._pks_changedN) rvrxryr6rFrPrQrRrSrdrtr"r"r"r#r{Cs)C>,"r{c@sNeZdZddZddZddZddZd d Zd d Zd dZ dddZ dS) ManyToOneDPcCs.t|||jjD]}|jt|qdSr%)r r$rZself_and_descendantsZ_dependency_processorsrEDetectKeySwitch)r!r rr"r"r#r$us  zManyToOneDP.__init__c Cs|jrbt||jjd}t||jjd} |j||f||f||f|| f|| f| |f| |fgn$|j||f||f||f||fgdSr1rrr}rr4r~r) r!r/r9r:r;r<r7r8parent_post_updatesparent_pre_updatesr"r"r#r6zs8  z%ManyToOneDP.per_property_dependenciesc Cs|jr|sZt||jjd} |r:|j|| f| |fgq|j||f||f|| fgqt||jjd} |j|| f| |f| |fgnL|s|s|j||f||fgq|j||fgn|r|j||fgdSr1r) r!r/rrrIr7r8rGrKrrr"r"r#rFsL z"ManyToOneDP.per_state_dependenciesc Cs|jjs|jjr|D]}|||j|j}|r|jjr@|}n|}|D]P}|dkrZqL|j|dd|j d|j d|}|D]\}} } } |j| ddqqLqdS)NTrrr) rrrrTrrsumZ non_deletedrr rr) r!rOrDr,rXZtodeleterHtrrrrr"r"r#rPs. zManyToOneDP.presort_deletesc Cs|D]}|j|d|jd|jjr|||j|j}|r|jD]T}||dkr>|j|dd|jd|j d|}|D]\}}} } |j| ddqvq>qdS)NrrFTrrr) rr rrrTrrrJr*rr) r!rOrDr,rXrHrrrrrr"r"r#rQs( zManyToOneDP.presort_savescCsn|jrj|jjsj|jdksj|D]L}||ddd||r|jr|||j|j}|r|j||| ddqdS)NrT)rq) rrrrrdrTrrrrr)r!rOrDr,rXr"r"r#rR s*  zManyToOneDP.process_deletesc Cs~|D]t}|||jtj}|r|jrF|jD]}|||dd|dq*n|jr`||ddd|d|jr|||| qdS)NFrTr) rTrrrrrdrJrrrr)r!rOrDr,rXrHr"r"r#rSs8 zManyToOneDP.process_savesNc Cs|dks|js||rdS|dk rX|dk rX|j|sXtdt|||jfdS|sd|dkrzt ||j |jj n(| |t ||j||j |jj |ddS)NGObject of type %s not in session, %s operation along '%s' won't proceedF)rrsession_contains_staterwarn mapperutilstate_class_strr rrrrr_rrr!r,rHrbrcrOrr"r"r#rd0s<    zManyToOneDP._synchronize)N) rvrxryr$r6rFrPrQrRrSrdr"r"r"r#rts(:rc@sheZdZdZddZddZddZdd Zd d Zd d Z ddZ ddZ ddZ ddZ ddZdS)raFor 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|jjDkr,dS||ddS)NFcss|] }|jVqdSr%)r)rer r"r"r# jsz=DetectKeySwitch.per_property_preprocessors..)r rhrr-r.r"r"r#r0esz*DetectKeySwitch.per_property_preprocessorscCs6t||jj}t||dd}|j||fgdSrM)rr3rr@r2r~r)r!r/r9r7r"r"r#r=rsz*DetectKeySwitch.per_property_flush_actionscCsdSr%r")r!r/rDrGr"r"r#rLwsz'DetectKeySwitch.per_state_flush_actionscCsdSr%r"rNr"r"r#rPzszDetectKeySwitch.presort_deletescCs|js|||dSr%)r_process_key_switches)r!r/rDr"r"r#rQ}szDetectKeySwitch.presort_savescCs"|s|jr|||}t|SdSrM)r_key_switchersbool)r!r/rDrGdr"r"r#rYs  z DetectKeySwitch.prop_has_changescCs dstdSrM)r?rNr"r"r#rRszDetectKeySwitch.process_deletescCs|js t|||dSr%)rr?rrNr"r"r#rSs zDetectKeySwitch.process_savescCsZ|d|fdd\}}||}|D].}||kr&|||rJ||q&||q&|S)NZ pk_switcherscSs ttfSr%)rlr"r"r"r#z0DetectKeySwitch._key_switchers..)rkunionrtr)r!r/rDZswitchedZ notswitchedZ allstatesrWr"r"r#rs    zDetectKeySwitch._key_switchersc Cs|||}|r|jjD]}t|j|jjs2q|j}||j j |||j d}|t j k r|dk r|jjr||srq|d}n|}t |}||kr||d|jt||j||j|jj||jqdS)N)rVF)rrZ identity_mapZ all_states issubclassr^rrCr)rgetrrZPASSIVE_NO_RESULTr r]Zinstance_staterrrrrr) r!ZdeplistrOZ switchersr,Zdict_rpZ related_objZ related_stater"r"r#rsH    z%DetectKeySwitch._process_key_switchescCs t|jot|||j|jjSr%)rrrrrr rrsr"r"r#rts zDetectKeySwitch._pks_changedN)rvrxry__doc__r0r=rLrPrQrYrRrSrrrtr"r"r"r#rYs  %rc@sTeZdZddZddZddZddZd d Zd d Zd dZ ddZ ddZ dS) ManyToManyDPc Cs:|j||f||f||f||f||f||f||fgdSr%r~r)r!r/r9r:r;r<r7r8r"r"r#r6s z&ManyToManyDP.per_property_dependenciesc CsX|s<|r"|j||f||fgqT|j||f||fgn|j||f||fgdSr%r) r!r/rrrIr7r8rGrKr"r"r#rFs z#ManyToManyDP.per_state_dependenciescCs&|js"|D]}|||j|jq dSr%)rrTrr)r!rOrDr,r"r"r#rPszManyToManyDP.presort_deletesc Cs|js.|D]"}|||r |||jtj}q |jjs:dS|D]r}|||jtj}|r>|j D]P}| |dkr^|j |dd|j d|j d|D]\}}}} |j |ddqq^q>dS)NFTrrr)rrtrTrrrrrrrJr*rr rr) r!rOrDr,rXrHrrrrr"r"r#rQs<  zManyToManyDP.presort_savesc sg}g}g}||}t}|D]||j|j}|r |D]F} | dksB|dk rd| f|krdqBi} || | d|ds~qB|| qB|fdd|Dq |dk r||| ||||dS)NFrc3s|]}|fVqdSr%r"rerr,r"r#rQsz/ManyToManyDP.process_deletes..) rmrlrTrrZ non_addedrdrEr _run_crud) r!rOrDsecondary_deletesecondary_insertsecondary_update processedtmprXrHrbr"rr#rR2sN     zManyToManyDP.process_deletesc sg}g}g}||}t}|D]:|j o8||}|rFtj} ntj} ||j| } | r | j D]>} |dk r| f|krqfi} | | | d|dsqf| | qf| j D]>} |dk rƈ| f|krqi} | | | d|dsq| | q| fdd| j | j D|r | jD]D} i} t |j| d|jjt | |j| d|jj| | qq |dk rr| ||||||dS)NFrrc3s|]}|fVqdSr%r"rrr"r#rsz-ManyToManyDP.process_saves..old_)rmrlrrtrrrrTrrrdrErJrrrrr rrsecondary_synchronize_pairsr) r!rOrDrrrrrZneed_cascade_pksrVrXrHrbr"rr#rSZs           zManyToManyDP.process_savescs|j|j}|r|d|jtjfdd|jjD}| ||}| r|j t |krt d|jjt ||j f|r|d|jtjfdd|jjD}| ||}| r|j t |krt d|jjt ||j f|r|j}| ||dS)Nrcs,g|]$}|jkr|tj|j|jdkqS)type_rr Z bindparamtyperrbr"r#rgs z*ManyToManyDP._run_crud..zRDELETE statement on table '%s' expected to delete %d row(s); Only %d were matched.cs0g|](}|jkr|tjd|j|jdkqS)rrrrrr"r#rgs zRUPDATE statement on table '%s' expected to update %d row(s); Only %d were matched.)Z transaction connectionrrrwherer and_rexecuteZsupports_sane_multi_rowcountZrowcountlenrZStaleDataError descriptionrinsert)r!rOrrrrZ statementresultr"rr#rs`          zManyToManyDP._run_crudcCs|||dkrdS|dk rP|j|sP|jsLtdt|||jfdSt ||j ||jj t ||j ||jjdS)NFrT)r_rrrJrrrrr rZ populate_dictrrrrrr"r"r#rds0 zManyToManyDP._synchronizecCst|||j|jjSr%rrsr"r"r#rts zManyToManyDP._pks_changedN) rvrxryr6rFrPrQrRrSrrdrtr"r"r"r#rs "(H=!rN)rrrrrrrZ interfacesrrr rr objectr r{rrrr&r"r"r"r#s<           ,3fu;