o
    Rc                     @   s   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 G dd deZG dd deZG dd deZG dd deZG dd deZeee
ee	eiZdS )zRelationship dependencies.

   )
attributes)exc)sync)
unitofwork)util)
MANYTOMANY)	MANYTOONE)	ONETOMANY   )sqlc                   @   s   e Zd Zdd Zedd Zdd Zdd Zd	d
 Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zd%ddZd d! Zd"d# Zd$S )&DependencyProcessorc                 C   s   || _ |j| _|j| _|j| _|j| _|j| _|j| _|j| _|j| _|j	| _	| jr/t
j| _nt
j| _| jr;t
j| _nt
j| _d| jj|jf | _|j| _| j jsYtd| j  d S )Nz%s_%sz|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    r"   ;D:\Flask\env\Lib\site-packages\sqlalchemy/orm/dependency.py__init__   s2   

zDependencyProcessor.__init__c                 C   s   t |j |S N)_direction_to_processorr   )clsr   r"   r"   r#   from_relationship7   s   z%DependencyProcessor.from_relationshipc                 C   s   | j j| j|S )zreturn True if the given object instance has a parent,
        according to the ``InstrumentedAttribute`` handled by this
        ``DependencyProcessor``.

        )r   Zclass_managerget_implr   	hasparentr!   stater"   r"   r#   r*   ;   s   zDependencyProcessor.hasparentc                 C   s   | | d dS )zestablish actions and dependencies related to a flush.

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

        TN)register_preprocessorr!   uowr"   r"   r#   per_property_preprocessorsC   s   z.DependencyProcessor.per_property_preprocessorsc              	   C   sz   t || dd}t || dd}t || jj}t || jj}t || jj}t || jj}| ||||||| d S NFT)r   
ProcessAllSaveUpdateAllr   primary_base_mapperr   	DeleteAllper_property_dependencies)r!   r/   
after_savebefore_deleteparent_saveschild_savesparent_deleteschild_deletesr"   r"   r#   per_property_flush_actionsL   s.   z.DependencyProcessor.per_property_flush_actionsc                 C   s  | j j}t||}t||}|rt|| dd}d|_nt|| dd}d|_||jvr@||jvs5J |df|dfg}	d}
nd}
|sXt|| jj	}d }}||jv rWd}nt|| jj	}d }}||jv rkd}|D ]}|j
| j j||j|r~| jntj}|sqm|rt|| d|}|rt||}nt|| d|}|rt||}|
rg }	|D ]+\}}||jvrd}n|j| \}}|rt||df}nt||df}|	| q|	D ]\}}| |||||||| qqmdS )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   r4   r   r3   r5   r2   disabledZcyclesr   base_mappermanagerr   implZget_all_pendingdictr   r   r   ZProcessStateZDeleteStateZSaveUpdateStatestatesappendper_state_dependencies)r!   r/   rC   isdeleteZchild_base_mapperr:   r<   r8   r7   Zchild_actionsZchild_in_cyclesr9   r;   Zparent_in_cyclesr,   Zsum_Zchild_statechildchild_actiondeletedZlistonlychildisdeleter"   r"   r#   per_state_flush_actionsh   s   	





z+DependencyProcessor.per_state_flush_actionsc                 C      dS NFr"   r!   	uowcommitrC   r"   r"   r#   presort_deletes      z#DependencyProcessor.presort_deletesc                 C   rL   rM   r"   rN   r"   r"   r#   presort_saves   rQ   z!DependencyProcessor.presort_savesc                 C      d S r%   r"   rN   r"   r"   r#   process_deletes   rQ   z#DependencyProcessor.process_deletesc                 C   rS   r%   r"   rN   r"   r"   r#   process_saves   rQ   z!DependencyProcessor.process_savesc                 C   sp   |r| j r	tj}n| jtu rtj}ntj}|D ]}||| j|}|r*|	 s* dS q|o7| j
j o7| j|jv S )NT)r   r   r   r   r   ZPASSIVE_NO_FETCH_RELATEDr   get_attribute_historyr   emptyr   Z_is_self_referentialr   Zmappers)r!   rO   rC   rF   passiveshistoryr"   r"   r#   prop_has_changes   s   


z$DependencyProcessor.prop_has_changesc                 C   s   | j jr|d u rtd| j f |d urG| jj|| j dsI| jj|ddr8td|j| j | jj| jd td|j| j | jjd d S d S )Nz-Can't flush None value found in collection %s)Z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zZ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   Z
FlushErrorr   Z_canloadr   class_r+   r"   r"   r#   _verify_canload   s8   
z#DependencyProcessor._verify_canloadc                 C      t  r%   NotImplementedError)r!   r,   rG   associationrow	clearkeysrO   r"   r"   r#   _synchronize(     z DependencyProcessor._synchronizec                 C   s>   | j jsd S tt| jgdd | j jD  }|d|ftS )Nc                 S   s   g | ]}|j qS r"   )r   ).0pr"   r"   r#   
<listcomp>0  s    zCDependencyProcessor._get_reversed_processed_set.<locals>.<listcomp>Zreverse_key)r   _reverse_propertytuplesortedr   memoset)r!   r/   Zprocess_keyr"   r"   r#   _get_reversed_processed_set+  s   z/DependencyProcessor._get_reversed_processed_setFc                 C   s:   |D ]}|r
|d ur| |dd | jjD   d S qd S )Nc                 S   s   g | ]\}}|qS r"   r"   )ri   lrr"   r"   r#   rk   8  s    z4DependencyProcessor._post_update.<locals>.<listcomp>)Zregister_post_updater   r   )r!   r,   rO   relatedis_m2o_deleter\   r"   r"   r#   _post_update4  s   z DependencyProcessor._post_updatec                 C   rb   r%   rc   r!   rO   r,   r"   r"   r#   _pks_changed<  rh   z DependencyProcessor._pks_changedc                 C   s   d| j j| jf S )Nz%s(%s))	__class____name__r   )r!   r"   r"   r#   __repr__?  s   zDependencyProcessor.__repr__N)F)rz   
__module____qualname__r$   classmethodr(   r*   r0   r=   rK   rP   rR   rT   rU   r[   ra   rg   rq   rv   rx   r{   r"   r"   r"   r#   r      s&    
	p)
	r   c                   @   sL   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dS )OneToManyDPc           
   
   C   s   | j r/t|| jjd}t|| jjd}	|j||f||f||f||	f|	|f|	|fg d S |j||f||f||f||f||f||f||fg d S r1   r   r   PostUpdateAllr   r4   dependenciesupdate)
r!   r/   r9   r:   r;   r<   r7   r8   child_post_updateschild_pre_updatesr"   r"   r#   r6   D  s4   


z%OneToManyDP.per_property_dependenciesc	                 C   s   | j rVt|| jjd}	t|| jjd}
|s8|r'|j||f||	fg d S |j||f||f||	fg d S |rH|j||
f|
|fg d S |j||
f|
|fg d S |si|j||f||f||fg d S |j||f||fg d S r1   r   )r!   r/   save_parentdelete_parentrH   r7   r8   rF   rJ   r   r   r"   r"   r#   rE   m  sR   

z"OneToManyDP.per_state_dependenciesc                 C   s   | j j o
| jdk }|D ]D}||| j| j}|rQ|jD ]}|d ur;| |du r;| j jr6|j	|dd q|	| q|rQ|j
D ]}|d urP|j	|d| jd qAqd S )NallFTrF   delete	operationr   )r   r   r   rV   r   r   rI   r*   delete_orphanregister_object	unchangedr   r!   rO   rC   should_null_fksr,   rZ   rG   r"   r"   r#   rP     s*   



zOneToManyDP.presort_deletesc              	   C   sN  | d| ft}| jj o| jdk }|D ]}| ||}|r"| jr&tj}ntj	}|
|| j|}|r|jD ]}	|	d urF|j|	dd| jd q6||j |jD ]9}	| jjsc|rb|j|	dd| jd qP| |	du r|j|	dd| jd | jd|	D ]\}
}}}|j|dd	 q{qP|r|r|jD ]}	|	d ur|j|	d| jd
| jd qqd S )Nchildren_addedr   Tadd)Zcancel_deleter   r   Fr   rF   r   r   r   z	pk changer   )ro   rp   r   r   r   rx   r   r   r   r   rV   r   addedr   r   r   rI   r*   r   cascade_iteratorr   )r!   rO   rC   r   r   r,   pks_changedrX   rZ   rG   cmst_dct_r"   r"   r#   rR     sp   





zOneToManyDP.presort_savesc              
   C   s   | j s| jdksu|d| ft}|D ]d}||| j| j}|rt|jD ]$}|d urF| |du rF| 	||d d|d | j rF|rF| 
|||g q"| j sN| jjstt|j|D ]}|d urs| 	||d d|d | j rs|rs| 
|||g qVqd S d S )Nr   r   FT)r   r   ro   rp   rV   r   r   rI   r*   rg   rv   r   r   r   
difference)r!   rO   rC   r   r,   rZ   rG   r"   r"   r#   rT   	  sB   




zOneToManyDP.process_deletesc              
   C   s   | j j o
| jdk }|D ]]}||| jtj}|rj|jD ]}| ||d d|d |d ur8| j	r8| 
|||g q|jD ]}|rS| j jsS| |sS| ||d d|d q<| ||rj|jD ]}| ||d d|d q]qd S )Nr   FT)r   r   r   rV   r   r   r   r   rg   r   rv   rI   r*   rx   r   r   r"   r"   r#   rU   5  sB   





zOneToManyDP.process_savesc           	   	   C   sr   |}|}|  | |d u s| js||rd S |r%t|| j| jj d S t|| j	|| j| jj|| j
o5| d S r%   )ra   r   
is_deletedr   clearr   r   r   populater   r   )	r!   r,   rG   re   rf   rO   r   sourcedestr"   r"   r#   rg   W  s(   
zOneToManyDP._synchronizec                 C      t ||| j| jjS r%   r   source_modifiedr   r   r   rw   r"   r"   r#   rx   n     zOneToManyDP._pks_changedN)rz   r|   r}   r6   rE   rP   rR   rT   rU   rg   rx   r"   r"   r"   r#   r   C  s    )C>,"r   c                   @   sP   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd Zdd Z		dddZ
dS )ManyToOneDPc                 C   s.   t | | | jjD ]
}|jt| q
d S r%   )r   r$   r   Zself_and_descendantsZ_dependency_processorsrD   DetectKeySwitch)r!   r   r   r"   r"   r#   r$   u  s   zManyToOneDP.__init__c           
   
   C   s   | j r2t|| jjd}t|| jjd}	|j||f||f||f||	f||	f|	|f|	|fg d S |j||f||f||f||fg d S r1   r   r   r   r   r4   r   r   )
r!   r/   r9   r:   r;   r<   r7   r8   parent_post_updatesparent_pre_updatesr"   r"   r#   r6   z  s0   

z%ManyToOneDP.per_property_dependenciesc	                 C   s   | j rI|s/t|| jjd}	|r|j||	f|	|fg d S |j||f||f||	fg d S t|| jjd}
|j||
f|
|f|
|fg d S |sf|s[|j||f||fg d S |j||fg d S |rs|j||fg d S d S r1   r   )r!   r/   r   r   rH   r7   r8   rF   rJ   r   r   r"   r"   r#   rE     sF   

z"ManyToOneDP.per_state_dependenciesc                 C   s   | j js| j jrP|D ]G}||| j| j}|rO| j jr | }n| }|D ](}|d u r-q&|j|dd| j	d | j
d|}|D ]\}}	}
}|j|
dd q@q&q
d S d S )NTr   r   r   )r   r   r   rV   r   r   sumZnon_deletedr   r   r   r   )r!   rO   rC   r,   rZ   ZtodeleterG   tr   r   r   r   r"   r"   r#   rP     s2   

zManyToOneDP.presort_deletesc                 C   s   |D ]H}|j |d| jd | jjrJ||| j| j}|rJ|jD ]*}| |du rI|j |dd| jd | j	
d|}|D ]\}}}	}
|j |	dd q;qqd S )Nr   r   FTr   r   r   )r   r   r   r   rV   r   r   rI   r*   r   r   )r!   rO   rC   r,   rZ   rG   r   r   r   r   r   r"   r"   r#   rR     s(   

zManyToOneDP.presort_savesc                 C   sz   | j r5| jjs7| jdks9|D ],}| |d d d| |r4| j r4||| j| j}|r4| j|||	 dd qd S d S d S d S )Nr   T)ru   )
r   r   r   r   rg   rV   r   r   rv   r   )r!   rO   rC   r,   rZ   r"   r"   r#   rT   	  s&   	

	zManyToOneDP.process_deletesc              
   C   s~   |D ]:}| || jtj}|r<|jr#|jD ]}| ||d d|d qn|jr0| |d d d|d | jr<| |||	  qd S )NFr   Tr   )
rV   r   r   r   r   rg   rI   r   rv   r   )r!   rO   rC   r,   rZ   rG   r"   r"   r#   rU     s&   

zManyToOneDP.process_savesNc              	   C   s   |d u s| j s||rd S |d ur,|d ur,|j|s,tdt||| jf  d S |s2|d u r>t	
|| j| jj d S | | t	|| j|| j| jj|d d S )NGObject of type %s not in session, %s operation along '%s' won't proceedF)r   r   session_contains_stater   warn
mapperutilstate_class_strr   r   r   r   r   ra   r   r   r!   r,   rG   re   rf   rO   r   r"   r"   r#   rg   0  s<   	

zManyToOneDP._synchronizer%   )rz   r|   r}   r$   r6   rE   rP   rR   rT   rU   rg   r"   r"   r"   r#   r   t  s    (:r   c                   @   sh   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd Zdd Zdd ZdS )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                 C   s<   | j jr| jr	d S ddd | j jD v rd S || d d S )NFc                 s   s    | ]}|j V  qd S r%   )r   )ri   r   r"   r"   r#   	<genexpr>j  s
    
z=DetectKeySwitch.per_property_preprocessors.<locals>.<genexpr>)r   rl   r   r-   r.   r"   r"   r#   r0   e  s   z*DetectKeySwitch.per_property_preprocessorsc                 C   s6   t || jj}t || dd}|j||fg d S rM   )r   r3   r   r?   r2   r   r   )r!   r/   r9   r7   r"   r"   r#   r=   r  s   z*DetectKeySwitch.per_property_flush_actionsc                 C   rS   r%   r"   )r!   r/   rC   rF   r"   r"   r#   rK   w  rQ   z'DetectKeySwitch.per_state_flush_actionsc                 C   rS   r%   r"   rN   r"   r"   r#   rP   z  rQ   zDetectKeySwitch.presort_deletesc                 C   s   | j s| || d S d S r%   r   _process_key_switches)r!   r/   rC   r"   r"   r#   rR   }  s   zDetectKeySwitch.presort_savesc                 C   s"   |s| j r| ||}t|S dS rM   )r   _key_switchersbool)r!   r/   rC   rF   dr"   r"   r#   r[     s   
z DetectKeySwitch.prop_has_changesc                 C   s   J r%   r"   rN   r"   r"   r#   rT     rQ   zDetectKeySwitch.process_deletesc                 C   s   | j sJ | || d S r%   r   rN   r"   r"   r#   rU     s   
zDetectKeySwitch.process_savesc                 C   sZ   | d| fdd \}}||}|D ]}||vr*| ||r%|| q|| q|S )NZpk_switchersc                   S   s   t  t  fS r%   )rp   r"   r"   r"   r#   <lambda>  s    z0DetectKeySwitch._key_switchers.<locals>.<lambda>)ro   unionrx   r   )r!   r/   rC   ZswitchedZnotswitchedZ	allstatesrY   r"   r"   r#   r     s   

zDetectKeySwitch._key_switchersc           	   
   C   s   |  ||}|rb|jj D ]U}t|j| jjsq|j}|| j	j
||| jd}|tjura|d ura| jjr>|s9q|d }n|}t|}||v ra||d| j t|| j|| j| jj|| j qd S d S )N)rX       F)r   r   Zidentity_mapZ
all_states
issubclassr`   r   rB   r)   r   getr   r   ZPASSIVE_NO_RESULTr   r_   Zinstance_stater   r   r   r   r   r   )	r!   ZdeplistrO   Z	switchersr,   Zdict_rt   Zrelated_objZrelated_stater"   r"   r#   r     sF   

z%DetectKeySwitch._process_key_switchesc                 C   s    t |jot||| j| jjS r%   )r   r   r   r   r   r   r   rw   r"   r"   r#   rx     s   zDetectKeySwitch._pks_changedN)rz   r|   r}   __doc__r0   r=   rK   rP   rR   r[   rT   rU   r   r   rx   r"   r"   r"   r#   r   Y  s    %r   c                   @   sT   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dd ZdS )ManyToManyDPc              
   C   s:   |j ||f||f||f||f||f||f||fg d S r%   r   r   )r!   r/   r9   r:   r;   r<   r7   r8   r"   r"   r#   r6     s   z&ManyToManyDP.per_property_dependenciesc	           	      C   s\   |s |r|j ||f||fg d S |j ||f||fg d S |j ||f||fg d S r%   r   )	r!   r/   r   r   rH   r7   r8   rF   rJ   r"   r"   r#   rE     s   z#ManyToManyDP.per_state_dependenciesc                 C   s*   | j s|D ]}||| j| j qd S d S r%   )r   rV   r   r   )r!   rO   rC   r,   r"   r"   r#   rP     s   
zManyToManyDP.presort_deletesc           
      C   s   | j s|D ]}| ||r||| jtj}q| jjsd S |D ]9}||| jtj}|rX|j	D ](}| 
|du rW|j|dd| jd | jd|D ]\}}}}	|j|dd qIq/qd S )NFTr   r   r   )r   rx   rV   r   r   r   r   r   r   rI   r*   r   r   r   r   )
r!   rO   rC   r,   rZ   rG   r   r   r   r   r"   r"   r#   rR     s8   


zManyToManyDP.presort_savesc              
      s   g }g }g }|  |}t }|D ]C | | j| j}|rS| D ]#}	|	d u s1|d ur2 |	f|v r2q!i }
|  |	|
d|ds?q!||
 q!| fdd| D  q|d ur]|| | 	|||| d S )NFr   c                 3       | ]}| fV  qd S r%   r"   ri   r   r,   r"   r#   r   Q      z/ManyToManyDP.process_deletes.<locals>.<genexpr>)
rq   rp   rV   r   r   Z	non_addedrg   rD   r   	_run_crud)r!   rO   rC   secondary_deletesecondary_insertsecondary_update	processedtmprZ   rG   re   r"   r   r#   rT   2  sF   



zManyToManyDP.process_deletesc              
      s  g }g }g }|  |}t }|D ] | j o| | }|r"tj}	ntj}	| | j|	}
|
r|
j	D ]}|d ur? |f|v r?q2i }| 
 ||d|dsLq2|| q2|
jD ]}|d urb |f|v rbqUi }| 
 ||d|dsoqU|| qU| fdd|
j	|
j D  |r|
jD ]!}i }t | j|d| jj t|| j|d| jj || qq|d ur|| | |||| d S )NFr   r   c                 3   r   r%   r"   r   r   r"   r#   r     r   z-ManyToManyDP.process_saves.<locals>.<genexpr>old_)rq   rp   r   rx   r   r   r   rV   r   r   rg   rD   rI   r   r   r   r   r   r   r   secondary_synchronize_pairsr   )r!   rO   rC   r   r   r   r   r   Zneed_cascade_pksrX   rZ   rG   re   r"   r   r#   rU   Z  s|   


 

zManyToManyDP.process_savesc                    s  |j | j}|rA|d  | j tj fdd| jjD  }|	||}|
 rA|jt|krAtd| jjt||jf |r{|d  | j tj fdd| jjD  }|	||}|
 r{|jt|kr{td| jjt||jf |r| j }|	|| d S d S )Nr   c                    s,   g | ]}|j  v r|tj|j |jd kqS )type_r   r   Z	bindparamtyper   re   r"   r#   rk     s    z*ManyToManyDP._run_crud.<locals>.<listcomp>zRDELETE statement on table '%s' expected to delete %d row(s); Only %d were matched.c                    s0   g | ]}|j  v r|tjd |j  |jdkqS )r   r   r   r   r   r"   r#   rk     s    zRUPDATE statement on table '%s' expected to update %d row(s); Only %d were matched.)Ztransaction
connectionr   r   r   wherer   and_r   executeZsupports_sane_multi_rowcountZrowcountlenr   ZStaleDataErrordescriptionr   insert)r!   rO   r   r   r   r   Z	statementresultr"   r   r#   r     sb   

	


	

zManyToManyDP._run_crudc                 C   s   |  | |d u rdS |d ur(|j|s(|js&tdt||| jf  dS t	
|| j|| jj t	
|| j|| jj dS )NFr   T)ra   r   r   rI   r   r   r   r   r   r   Zpopulate_dictr   r   r   r   r   r"   r"   r#   rg     s*   
zManyToManyDP._synchronizec                 C   r   r%   r   rw   r"   r"   r#   rx      r   zManyToManyDP._pks_changedN)rz   r|   r}   r6   rE   rP   rR   rT   rU   r   rg   rx   r"   r"   r"   r#   r     s    "(H=!r   N)r    r   r   r   r   r   r   Z
interfacesr   r   r	   r   r   objectr   r   r   r   r   r&   r"   r"   r"   r#   <module>   s8     ,  3 fu  ;