
    h'                       d Z ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ	 dd	l
mZ dd
l
mZ ddl
mZ ddlmZ ddlmZ ddlmZ  G d d      Z G d de      Z G d de      Z G d de      Z G d de      ZeeeeeeiZy)zRelationship dependencies.

    )annotations   )
attributes)exc)sync)
unitofwork)util)
MANYTOMANY)	MANYTOONE)	ONETOMANY   )sqlc                  ~    e Zd Zd Zed        Zd Zd Zd Zd Z	d Z
d Zd	 Zd
 Zd Zd Zd Zd ZddZd Zd Zy)DependencyProcessorc                   || _         |j                  | _        |j                  | _        |j                  | _        |j                  | _        |j
                  | _        |j                  | _        |j                  | _        |j                  | _        |j                  | _	        | j                  rt        j                  | _        nt        j                  | _        | j                  rt        j                  | _        nt        j                  | _        | j                  j                  d|j                   | _        |j                   | _        | j                   j$                  s"t'        j(                  d| j                   z        y )N_z|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	_sort_keykeysort_keysynchronize_pairssa_excArgumentError)selfr   s     BD:\EasyAligner\venv\Lib\site-packages\sqlalchemy/orm/dependency.py__init__zDependencyProcessor.__init__   s   	||kkkk++#33#33!%!7!7(2(H(HD%(2(>(>D%(2(H(HD%(2(>(>D%#';;#8#8$((C88yy**&&$&*ii0  +    c                2    t        |j                     |      S N)_direction_to_processorr   )clsr   s     r(   from_relationshipz%DependencyProcessor.from_relationship;   s    &t~~6t<<r*   c                ~    | j                   j                  j                  | j                        j	                  |      S )zreturn True if the given object instance has a parent,
        according to the ``InstrumentedAttribute`` handled by this
        ``DependencyProcessor``.

        )r   class_managerget_implr"   	hasparentr'   states     r(   r3   zDependencyProcessor.hasparent?   s.     {{((11$((;EEeLLr*   c                (    |j                  | d       y)zestablish actions and dependencies related to a flush.

        These actions will operate on all relevant states in
        the aggregate.

        TN)register_preprocessorr'   uows     r(   per_property_preprocessorsz.DependencyProcessor.per_property_preprocessorsG   s     	!!$-r*   c           	        t        j                  || dd      }t        j                  || dd      }t        j                  || j                  j                        }t        j                  || j
                  j                        }t        j                  || j                  j                        }t        j                  || j
                  j                        }| j                  |||||||       y NFT)r   
ProcessAllSaveUpdateAllr   primary_base_mapperr   	DeleteAllper_property_dependencies)r'   r9   
after_savebefore_deleteparent_saveschild_savesparent_deleteschild_deletess           r(   per_property_flush_actionsz.DependencyProcessor.per_property_flush_actionsP   s    **3eTB
"--c4tD!//00
 !..00
 $--00
 #,,00
 	&&	
r*   c                   | j                   j                  }t        j                  ||      }t        j                  ||      }|r t        j
                  || dd      }d|_        nt        j
                  || dd      }d|_        ||j                  vr||j                  vsJ |df|dfg}	d}
nd}
|s?t        j                  || j                  j                        }dx}}||j                  v rAd}n>t        j                  || j                  j                        }dx}}||j                  v rd}|D ]Z  }|j                  | j                     j                  j                  ||j                  |r| j                  nt         j"                        }|sa|r1t        j$                  || d|      }rGt        j&                  ||      }n0t        j$                  || d|      }rt        j(                  ||      }|
rsg }	|D ]l  \  }}||j*                  vrd}nE|j*                  |   \  }}|rt        j&                  ||      df}nt        j(                  ||      df}|	j-                  |       n 	D ]  \  }}| j/                  ||||||        ] y)zestablish 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)r   r?   r   r>   r@   r=   disabledcyclesr   base_mappermanagerr"   implget_all_pendingdictr   r   r   ProcessStateDeleteStateSaveUpdateStatestatesappendper_state_dependencies)r'   r9   rT   isdeletechild_base_mapperrE   rG   rC   rB   child_actionschild_in_cyclesrD   rF   parent_in_cyclesr5   sum_child_statechildchild_actiondeletedlistonlychildisdeletes                         r(   per_state_flush_actionsz+DependencyProcessor.per_state_flush_actionsl   s    !KK;; ..s4EF",,S2CD
 &11#tT4HM%)M"#..sD%FJ"&J cjj(
 !

222 *51M43HIM#O"O %33T[[,,L .21N]szz)#' '11#t{{7N7NON(,,L:+#'  E ==*//??

   --#99D  * 7 7T4 O#%/%;%;C%GN'44S$uM
##-#=#=c5#IL "*.&K"#**4'3.1jj.E+(" * 6 6sK H $,L !+ : :3 L %,L "((6 +/& 0=+m++ " !!	 0=_ r*   c                     yNF r'   	uowcommitrT   s      r(   presort_deletesz#DependencyProcessor.presort_deletes       r*   c                     yre   rf   rg   s      r(   presort_savesz!DependencyProcessor.presort_saves   rj   r*   c                     y r,   rf   rg   s      r(   process_deletesz#DependencyProcessor.process_deletes       r*   c                     y r,   rf   rg   s      r(   process_savesz!DependencyProcessor.process_saves   ro   r*   c                   |r| j                   r"t        j                  t        j                  z  }nD| j                  t
        u rt        j                  }n!t        j                  t        j                  z  }|D ]4  }|j                  || j                  |      }|s#|j                         r4 y |xr1 | j                  j                   xr | j                  |j                  v S )NT)r   r   r   INCLUDE_PENDING_MUTATIONSr   r   PASSIVE_NO_FETCH_RELATEDr   get_attribute_historyr"   emptyr   _is_self_referentialr   mappers)r'   rh   rT   rW   passiveshistorys          r(   prop_has_changesz$DependencyProcessor.prop_has_changes   s    4//00667  ^^y( !99G &&)M)MM  A  55a7KGw}}   5		6665KK9#4#44r*   c                .   | j                   j                  r$|"t        j                  d| j                         || j                  j                  || j                         s| j                  j                  |d      rOt        j                  d|j                  | j                   | j                  j                  | j                  dz        t        j                  d|j                  | j                   | j                  j                  dz        y y )Nz+Can't flush None value found in collection )allow_subtypesTaE  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. 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zzmzAttempting 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.)r   r   r   )r   uselistr   
FlushErrorr   _canloadr   class_r4   s     r(   _verify_canloadz#DependencyProcessor._verify_canload
  s    99..#'99/  t{{';';d&<&<"< (< (
 {{##E$#?nn= #\\!YY![[//"kk	 $ nn! #\\!YY![[//	 -(
r*   c                    t               r,   NotImplementedError)r'   r5   r^   associationrow	clearkeysrh   s         r(   _synchronizez DependencyProcessor._synchronize3      !##r*   c           	        | j                   j                  sy t        t        | j                  g| j                   j                  D cg c]  }|j                   c}z               }|j                  d|ft              S c c}w )Nreverse_key)r   _reverse_propertytuplesortedr"   memoset)r'   r9   pprocess_keys       r(   _get_reversed_processed_setz/DependencyProcessor._get_reversed_processed_set6  sl    yy**DHH:		0K0K L0K10K LLM
 xx4c:: !Ms   A>c           
         |D ]A  }|r||j                  || j                  j                  D cg c]  \  }}|	 c}}        y  y c c}}w r,   )register_post_updater   r$   )r'   r5   rh   relatedis_m2o_deleter   lrs           r(   _post_updatez DependencyProcessor._post_update?  sP    A AM..$))*E*EF*E$!QA*EF   Gs   Ac                    t               r,   r   r'   rh   r5   s      r(   _pks_changedz DependencyProcessor._pks_changedG  r   r*   c                N    | j                   j                  d| j                  dS )N())	__class____name__r   )r'   s    r(   __repr__zDependencyProcessor.__repr__J  s    >>22DII>>r*   N)F)r   
__module____qualname__r)   classmethodr/   r3   r:   rH   rc   ri   rl   rn   rq   r|   r   r   r   r   r   r   rf   r*   r(   r   r      sk    : = =M.
8pd@'R$;$?r*   r   c                  <    e Zd Zd Zd Zd Zd Zd Zd Zd Z	d Z
y	)
OneToManyDPc           
        | j                   rt        j                  || j                  j                  d      }t        j                  || j                  j                  d      }	|j
                  j                  ||f||f||f||	f|	|f|	|fg       y |j
                  j                  ||f||f||f||f||f||f||fg       y r<   r   r   PostUpdateAllr   r?   dependenciesupdate)
r'   r9   rD   rE   rF   rG   rB   rC   child_post_updateschild_pre_updatess
             r(   rA   z%OneToManyDP.per_property_dependenciesO  s     !+!9!9T[[44e" !+ 8 8T[[44d! ## *-!:.!34"$56&7&6	 ##!:.-/ .1"N3"K0"M2
r*   c	                z   | j                   rt        j                  || j                  j                  d      }	t        j                  || j                  j                  d      }
|sI|r"|j
                  j                  ||f||	fg       y |j
                  j                  ||f||f||	fg       y |r"|j
                  j                  ||
f|
|fg       y |j
                  j                  ||
f|
|fg       y |s%|j
                  j                  ||f||f||fg       y |j
                  j                  ||f||fg       y r<   r   )r'   r9   save_parentdelete_parentr_   rB   rC   rW   rb   r   r   s              r(   rV   z"OneToManyDP.per_state_dependenciesx  sr    !+!9!9T[[44e" !+ 8 8T[[44d!  $$++):6');< $$++(*5):6');< !$$++*,=>.> $$++*,=>.> ## *-. ,/ ##.}0MNr*   c                   | j                   j                   xr | j                  dk(   }|D ]  }|j                  || j                  | j
                        }|s-|j                  D ]T  }|| j                  |      du s| j                   j                  r|j                  |d       D|j                  |       V |s|j                  D ]#  }||j                  |d| j                         %  y )NallFTrW   delete	operationr   )r   r   r   ru   r"   r   r`   r3   delete_orphanregister_object	unchangedr   r'   rh   rT   should_null_fksr5   r{   r^   s          r(   ri   zOneToManyDP.presort_deletes  s    
 ###ID,@,@E,I(I 	 E55txx!:!:G $__E(T^^E-Be-K<<55%55ed5K%55e< - #!(!2!2 ,%55 %		 6  "3 r*   c           	     2   |j                  d| ft              }| j                  j                   xr | j                  dk(   }|D ]  }| j                  ||      }|r| j                  r"t        j                  t        j                  z  }n!t        j                  t        j                  z  }|j                  || j                  |      }|r|j                  D ]$  }	|	|j                  |	dd| j                         & |j!                  |j                         |j"                  D ]  }	| j                  j                  s#|s|j                  |	dd| j                         <| j%                  |	      du sP|j                  |	dd| j                         | j&                  j)                  d|	      D ]  \  }
}}}|j                  |d	         |s|s|j*                  D ]/  }	|	|j                  |	d| j                  d
| j                         1  y )Nchildren_addedr   Tadd)cancel_deleter   r   Fr   rW   r   r   r   z	pk changer   )r   r   r   r   r   r   r   r   r   rs   r   ru   r"   addedr   r   r   r`   r3   r   cascade_iteratorr   )r'   rh   rT   r   r   r5   pks_changedry   r{   r^   cmst_dct_s                 r(   rl   zOneToManyDP.presort_saves  s   ")94(@#F *** 2((E11 	
 E++Iu=K$"6"644 ::;  ** ::; 
  55eTXXwOG$]]E(!11!*.&+!%	 2  + %%gmm4$__E<<55*%55 %).*2%)YY	 6  .%7!11!%)&.!%	 2  04{{/K/K$e0OAq#t &55cD5I0! -* !(!2!2 ,%55 % % $ 4 4*5%)YY 6  "3e r*   c           
        | j                   s| j                  dk(  s7|j                  d| ft              }|D ]  }|j	                  || j
                  | j                        }|s.|j                  D ]S  }|| j                  |      du s| j                  ||d d|d       | j                   s=|s@| j                  |||g       U | j                   s| j                  j                  rt        |j                        j                  |      D ]?  }|| j                  ||d d|d       | j                   s)|s,| j                  |||g       A  y y )Nr   r   FT)r   r   r   r   ru   r"   r   r`   r3   r   r   r   r   r   
difference)r'   rh   rT   r   r5   r{   r^   s          r(   rn   zOneToManyDP.process_deletes  sH    4#7#75#@&^^-=t,DcJN#99488T%>%> !(!- $u 5 > -- %udD)U  $//E $ 1 1%UG L "1 ''t||/B/B%():):%;%F%F*&E  %0 $ 1 1$)5$i!" $(#3#3$($5$5(-y5'%&&#   $Ar*   c           
     t   | j                   j                   xr | j                  dk(   }|D ]	  }|j                  || j                  t
        j                        }|s2|j                  D ]<  }| j                  ||d d|d       || j                  s)| j                  |||g       > |j                  D ]D  }|s| j                   j                  r| j                  |      r/| j                  ||d d|d       F | j                  ||      s|j                  D ]  }| j                  ||d d|d         y )Nr   FT)r   r   r   ru   r"   r   r   r   r   r   r   r`   r3   r   r   r   s          r(   rq   zOneToManyDP.process_savesD  s0   *** 2((E11 	
 E55txx!A!AG $]]E%%udE9e (T-=-=))%UGD + %__E' $ : : $u 5))!5$i - $$Y6!(!2!2))!5$y$ "3/ r*   c           
        |}|}| j                  |       || j                  s|j                  |      ry |r6t        j                  || j
                  | j                  j                         y t        j                  || j                  || j
                  | j                  j                  || j                  xr |       y r,   )r   r   
is_deletedr   clearr   r   r$   populater   r   )	r'   r5   r^   r   r   rh   r   sourcedests	            r(   r   zOneToManyDP._synchronizef  s     U#<  Y%9%9$%?JJtT[[$))*E*EFMM		++$$4r*   c                n    t        j                  ||| j                  | j                  j                        S r,   r   source_modifiedr   r   r$   r   s      r(   r   zOneToManyDP._pks_changed}  ,    ##udkk499+F+F
 	
r*   N)r   r   r   rA   rV   ri   rl   rn   rq   r   r   rf   r*   r(   r   r   N  s0    'R?B6BH%&X D.
r*   r   c                  @    e Zd Zd Zd Zd Zd Zd Zd Zd Z		 d
d	Z
y)ManyToOneDPc                    t         j                  | |       | j                  j                  D ]&  }|j                  j                  t        |             ( y r,   )r   r)   r   self_and_descendants_dependency_processorsrU   DetectKeySwitch)r'   r   r   s      r(   r)   zManyToOneDP.__init__  s?    $$T40kk66F))001FG 7r*   c           
     x   | j                   rt        j                  || j                  j                  d      }t        j                  || j                  j                  d      }	|j
                  j                  ||f||f||f||	f||	f|	|f|	|fg       y |j
                  j                  ||f||f||f||fg       y r<   r   r   r   r   r?   r   r   )
r'   r9   rD   rE   rF   rG   rB   rC   parent_post_updatesparent_pre_updatess
             r(   rA   z%ManyToOneDP.per_property_dependencies  s     ",":":T[[44e# ",!9!9T[[44d" ## *-!:.!45!34"$67'7'8
 ## *-.!=1#]3	r*   c	                t   | j                   r|stt        j                  || j                  j                  d      }	|r"|j
                  j                  ||	f|	|fg       y |j
                  j                  ||f||f||	fg       y t        j                  || j                  j                  d      }
|j
                  j                  ||
f|
|f|
|fg       y |sC|s"|j
                  j                  ||f||fg       y |j
                  j                  ||fg       y |r|j
                  j                  ||fg       y y r<   r   )r'   r9   r   r   r_   rB   rC   rW   rb   r   r   s              r(   rV   z"ManyToOneDP.per_state_dependencies  s_    &0&>&>88%'# !$$++')<=0,? $$++(*5):6')<= &0%=%=88$&"   ''&(:;+];+\:    ''"J/*k1JK   ''*k)B(CD   ''-)F(GH r*   c                   | j                   j                  s| j                   j                  r|D ]  }|j                  || j                  | j
                        }|s-| j                   j                  r|j                         }n|j                         }|D ]_  }||j                  |dd| j                         | j                  j                  d|      }|D ]  \  }}	}
}|j                  |
d        a  y y )NTr   r   r   )r   r   r   ru   r"   r   sumnon_deletedr   r   r   r   )r'   rh   rT   r5   r{   todeleter^   tr   r   r   r   s               r(   ri   zManyToOneDP.presort_deletes  s    <<$,,"<"<#99488T%>%> ||11#*;;=#*#6#6#8!) =$!11!%)&.!%	 2  !KK885I/0OAq#t%55cD5I 01 "*   #=r*   c                   |D ]  }|j                  |d| j                         | j                  j                  s8|j	                  || j
                  | j                        }|sb|j                  D ]p  }| j                  |      du s|j                  |dd| j                         | j                  j                  d|      }|D ]  \  }}}	}
|j                  |	d        r  y )Nr   r   FTr   r   r   )r   r   r   r   ru   r"   r   r`   r3   r   r   )r'   rh   rT   r5   r{   r^   r   r   r   r   r   s              r(   rl   zManyToOneDP.presort_saves   s    E%%eu499%M||))#99488T%>%> !(>>%0E9%55 %)-*2%)YY	 6  !% < <Xu MA341c4 ) 9 9# 9 M 45 "1 r*   c                ^   | j                   r| j                  j                  s| j                  dk(  sz|D ]t  }| j	                  |d d d|       |s| j                   s(|j                  || j                  | j                        }|sR| j                  |||j                         d       v y y y y )Nr   T)r   )
r   r   r   r   r   ru   r"   r   r   r   )r'   rh   rT   r5   r{   s        r(   rn   zManyToOneDP.process_deletes  s    LL..((E1
  !!%tT9ET--'==txx)B)BG ))!9gkkm4 *    2 / r*   c           
     v   |D ]  }|j                  || j                  t        j                        }|s1|j                  r(|j                  D ]  }| j                  ||d d|d        n"|j                  r| j                  |d d d|d       | j                  s| j                  |||j                                 y )NFr   Tr   )
ru   r"   r   r   r   r   r`   r   r   r   )r'   rh   rT   r5   r{   r^   s         r(   rq   zManyToOneDP.process_saves)  s    E55txx!A!AG ==!())!5$y% "/ __%%tT4H ##%%eYF r*   Nc           	        || j                   s|j                  |      ry |Z|X|j                  j                  |      s=t	        j
                  dt        j                  |      d|d| j                  d       y |s|6t        j                  || j                  | j                  j                         y | j                  |       t        j                  || j                  || j                  | j                  j                  |d       y )NObject of type  not in session,  operation along '' won't proceedF)r   r   session_contains_stater	   warn
mapperutilstate_class_strr   r   r   r   r$   r   r   r   r'   r5   r^   r   r   rh   r   s          r(   r   zManyToOneDP._synchronize;  s     =  Y%9%9%%@ !!%%55e<II --e4iL
 JJudkk499+F+FG  'MM		++r*   r,   )r   r   r   r)   rA   rV   ri   rl   rn   rq   r   rf   r*   r(   r   r     s6    H
%N6IpJ0N*(G2 &r*   r   c                  R    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zy)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.

    c                    | j                   j                  r-| j                  ry dd | j                   j                  D        v ry |j                  | d       y )NFc              3  4   K   | ]  }|j                     y wr,   )r   ).0r   s     r(   	<genexpr>z=DetectKeySwitch.per_property_preprocessors.<locals>.<genexpr>u  s       ; (( ;s   )r   r   r   r7   r8   s     r(   r:   z*DetectKeySwitch.per_property_preprocessorsp  sO    99&&##  $		 ; ;  !!$.r*   c                    t        j                  || j                  j                        }t        j                  || dd      }|j
                  j                  ||fg       y re   )r   r>   r   rL   r=   r   r   )r'   r9   rD   rB   s       r(   rH   z*DetectKeySwitch.per_property_flush_actions}  sP    !//T[[5L5LM**3eUC
,
!; <=r*   c                     y r,   rf   )r'   r9   rT   rW   s       r(   rc   z'DetectKeySwitch.per_state_flush_actions  ro   r*   c                     y r,   rf   rg   s      r(   ri   zDetectKeySwitch.presort_deletes  ro   r*   c                B    | j                   s| j                  ||       y y r,   r   _process_key_switches)r'   r9   rT   s      r(   rl   zDetectKeySwitch.presort_saves  s"    ## &&vs3 $r*   c                Z    |s)| j                   r| j                  ||      }t        |      S yre   )r   _key_switchersbool)r'   r9   rT   rW   ds        r(   r|   z DetectKeySwitch.prop_has_changes  s+    D00##C0A7Nr*   c                    J r,   rf   rg   s      r(   rn   zDetectKeySwitch.process_deletes  s    ur*   c                D    | j                   sJ | j                  ||       y r,   r  rg   s      r(   rq   zDetectKeySwitch.process_saves  s#    
 ####""695r*   c                    |j                  d| fd       \  }}|j                  |      }|D ]<  }||vs| j                  ||      r|j                  |       ,|j                  |       > |S )Npk_switchersc                 *    t               t               fS r,   )r   rf   r*   r(   <lambda>z0DetectKeySwitch._key_switchers.<locals>.<lambda>  s    SUCENr*   )r   unionr   r   )r'   r9   rT   switchednotswitched	allstatesrz   s          r(   r  zDetectKeySwitch._key_switchers  sp     #T"$:!
+ NN;/	A	!$$S!,LLOOOA&  r*   c           
        | j                  ||      }|rU|j                  j                  j                         D ],  }t	        |j
                  | j                  j
                        s/|j                  }|j                  | j                        j                  ||| j                        }|t        j                  us|| j                  j                  r	|s|d   }n|}t        j                   |      }||v s|j#                  |d| j$                         t'        j(                  || j*                  || j                  | j                  j,                  || j$                         / y y )N)ry   r   F)r  r   identity_map
all_states
issubclassr   r   rP   r2   r"   getr    r   PASSIVE_NO_RESULTr   r   instance_stater   r   r   r   r   r$   )	r'   deplistrh   	switchersr5   dict_r   related_objrelated_states	            r(   r  z%DetectKeySwitch._process_key_switches  s6   ''	7;	 #**77BBD!%,,0B0BC

..2665$*C*C 7  :#?#??+yy((&$&-aj&-$.$=$=k$JM$	1!11!5$*>*> ) KK! KK II77% 00- E r*   c                    t        |j                        xr6 t        j                  ||| j                  | j
                  j                        S r,   )r  r"   r   r   r   r   r$   r   s      r(   r   zDetectKeySwitch._pks_changed  s;    EII 
4#7#7udkk499+F+F$
 	
r*   N)r   r   r   __doc__r:   rH   rc   ri   rl   r|   rn   rq   r  r  r   rf   r*   r(   r   r   d  s?    	/>
46#J
r*   r   c                  B    e Zd Zd Zd Zd Zd Zd Zd Zd Z	d Z
d	 Zy
)ManyToManyDPc           
     d    |j                   j                  ||f||f||f||f||f||f||fg       y r,   r   r   )r'   r9   rD   rE   rF   rG   rB   rC   s           r(   rA   z&ManyToManyDP.per_property_dependencies  sW     	z*j)]+ -/.,	
r*   c	                    |sF|r"|j                   j                  ||f||fg       y |j                   j                  ||f||fg       y |j                   j                  ||f||fg       y r,   r$  )	r'   r9   r   r   r_   rB   rC   rW   rb   s	            r(   rV   z#ManyToManyDP.per_state_dependencies  s       ''!:.\0JK   ''!:.z0JK ##.0NOr*   c                z    | j                   s/|D ])  }|j                  || j                  | j                         + y y r,   )r   ru   r"   r   )r'   rh   rT   r5   s       r(   ri   zManyToManyDP.presort_deletes  s=     ##  //488T%>%>  	 $r*   c                8   | j                   sE|D ]@  }| j                  ||      s|j                  || j                  t        j
                        }B | j                  j                  sy |D ]  }|j                  || j                  t        j                        }|s1|j                  D ]n  }| j                  |      du s|j                  |dd| j                         | j                  j                  d|      D ]  \  }}}}	|j                  |d        p  y )NFTr   r   r   )r   r   ru   r"   r   r   r   r   r   r`   r3   r   r   r   r   )
r'   rh   rT   r5   r{   r^   r   r   r   r   s
             r(   rl   zManyToManyDP.presort_saves  s   ##  $$Y6'==txx)?)?G   ||)) E55txx!A!AG $__E~~e,5!11!%)&.!%	 2  04{{/K/K$e0OAq#t &55cD5I0 - r*   c           
        g }g }g }| j                  |      }t               }|D ]  |j                  | j                  | j                        }|s-|j                         D ]7  }	|	||	f|v ri }
| j                  |	|
d|d      s'|j                  |
       9 |j                  fd|j                         D                ||j                  |       | j                  ||||       y )NFr   c              3  &   K   | ]  }|f 
 y wr,   rf   r   r   r5   s     r(   r   z/ManyToManyDP.process_deletes.<locals>.<genexpr>[  s     C/B!Au:/B   )
r   r   ru   r"   r   	non_addedr   rU   r   	_run_crud)r'   rh   rT   secondary_deletesecondary_insertsecondary_update	processedtmpr{   r^   r   r5   s              @r(   rn   zManyToManyDP.process_deletes<  s   44Y?	eE  55txx!:!:G $..0E}!-5%.I2M %'N,,&!  !$++N; 1" 

Cw/@/@/BCC1 4  S!')9;K	
r*   c           
     R   g }g }g }| j                  |      }t               }|D ]  | j                   xr | j                  |      }|r"t        j
                  t        j                  z  }	n!t        j                  t        j                  z  }	|j                  | j                  |	      }
|
s|
j                  D ]5  }||f|v ri }| j                  ||d|d      s%|j                  |       7 |
j                  D ]5  }||f|v ri }| j                  ||d|d      s%|j                  |       7 |j                  fd|
j                  |
j                  z   D               |sG|
j                  D ]  }i }t!        j                  | j"                  |d| j$                  j&                         t!        j                  || j(                  |d| j$                  j*                         |j                  |         ||j                  |       | j-                  ||||       y )NFr   r   c              3  &   K   | ]  }|f 
 y wr,   rf   r*  s     r(   r   z-ManyToManyDP.process_saves.<locals>.<genexpr>  s     O/N!Au:/Nr+  old_)r   r   r   r   r   r   rs   r   ru   r"   r   r   rU   r`   r   r   r   r   r   r$   r   secondary_synchronize_pairsr-  )r'   rh   rT   r.  r/  r0  r1  r2  need_cascade_pksry   r{   r^   r   r5   s                @r(   rq   zManyToManyDP.process_savesd  s6   44Y?	eE#'#7#77  D<M<M5=  ** ::;  44 ::;   55eTXXwOG$]]E ,%91L %'N,,uneY !$++N; + %__E ,%91L %'N,,&!  !$++N; - 

Ow}}w/NOO#!(!2!2)+! KK*" II77 ! KK*" IIAA )//?# "3W |  S!')9;K	
r*   c                *   |j                   j                  | j                        }|r|d   }| j                  j	                         j                  t        j                  | j                  j                  D cg c]>  }|j                  |v r.|t        j                  |j                  |j                        k(  @ c}       }|j                  ||      }	|	j                         rZ|	j                  t        |      k7  rBt!        j"                  d| j                  j$                  t        |      |	j                  fz        |r|d   }| j                  j'                         j                  t        j                  | j                  j                  D cg c]A  }|j                  |v r1|t        j                  d|j                  z   |j                        k(  C c}       }|j                  ||      }	|	j                         rZ|	j                  t        |      k7  rBt!        j"                  d| j                  j$                  t        |      |	j                  fz        |r-| j                  j)                         }|j                  ||       y y c c}w c c}w )Nr   )type_zRDELETE statement on table '%s' expected to delete %d row(s); Only %d were matched.r5  zRUPDATE statement on table '%s' expected to update %d row(s); Only %d were matched.)transaction
connectionr   r   r   wherer   and_r   r"   	bindparamtypeexecutesupports_sane_multi_rowcountrowcountlenr   StaleDataErrordescriptionr   insert)
r'   rh   r/  r0  r.  r;  r   r   	statementresults
             r(   r-  zManyToManyDP._run_crud  sJ    **55dkkB
-a0N--/55 "&!1!1!1A55N2 S]]155??!1I  ''	3CDF 335//S)9%::((7 22,-  -a0N--/55 "&!1!1!1A55N2 S]]6AEE>HH!1I  ''	3CDF 335//S)9%::((7 22,-  --/Iy*:; a4s   8AJAJc           	        | j                  |       |y|d|j                  j                  |      sI|j                  s<t	        j
                  dt        j                  |      d|d| j                  d       yt        j                  || j                  || j                  j                         t        j                  || j                  || j                  j                         y)NFr   r   r   r   T)r   r   r   r`   r	   r   r   r   r   r   populate_dictr   r$   r   r6  r   s          r(   r   zManyToManyDP._synchronize  s     	U# =Y%6%6%F%Fu%M==		 "11%8)TYYP
 4;;		0K0K	
 	KKII11		
 r*   c                n    t        j                  ||| j                  | j                  j                        S r,   r   r   s      r(   r   zManyToManyDP._pks_changed  r   r*   N)r   r   r   rA   rV   ri   rl   rn   rq   r-  r   r   rf   r*   r(   r"  r"    s6    
62
 JD&
PK
Z;<z@
r*   r"  N)r   
__future__r    r   r   r   r   r	   r   
interfacesr
   r   r   r%   r   r   r   r   r   r"  r-   rf   r*   r(   <module>rO     s    #       " ! !   n? n?b	r
% r
j	^% ^Br
) r
jx
& x
x	 {{ r*   