B
    \}                 @   s4  d Z ddlmZ ddl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 e Zdd Zedd-ddZdd Zd.ddZd/ddZd0ddZd1ddZdd  Zd!d" Zd#d$ Zd%d& Z d'd( Z!G d)d* d*e"Z#d+d, Z$dS )2zprivate module containing functions used to convert database
rows into object instances and associated state.

the functions here are called primarily by Query, Mapper,
as well as some of the attribute loading strategies.

    )absolute_importN   )
attributes)exc)path_registry)strategy_options)_DEFER_FOR_STATE)_SET_DEFERRED_EXPIRED)	_none_set)	state_str   )utilc          
   #   sz  t   _i  _j}j o4tjdko4jd j}|rP|rDt}nfdd}yt	t
 fddjD  \}|std|xi  _jrj}|sP n }|rЈd fdd|D }nfd	d|D }x" j D ]\}	}
|
 |	 qW |rt||}x|D ]}|V  q W jsP qW W n6 tk
rt } z  t| W d
d
}~X Y nX d
S )z$Return an ORM result as an iterator.r   r   c                s   t dd t j| D S )Nc             s   s$   | ]\}}|j rt|n|V  qd S )N)Zuse_id_for_hashid).0entitem r   5lib/python3.7/site-packages/sqlalchemy/orm/loading.py	<genexpr>8   s   z/instances.<locals>.filter_fn.<locals>.<genexpr>)tuplezip	_entities)row)queryr   r   	filter_fn6   s    zinstances.<locals>.filter_fnc                s   g | ]}|  qS r   )Zrow_processor)r   query_entity)contextcursorr   r   r   
<listcomp>@   s   zinstances.<locals>.<listcomp>resultc                s   g | ]} |qS r   r   )r   r   )procr   r   r   U   s    c                s"   g | ]  fd dD qS )c                s   g | ]}| qS r   r   )r   r    )r   r   r   r   X   s    z(instances.<locals>.<listcomp>.<listcomp>r   )r   )keyed_tupleprocess)r   r   r   X   s   N)
_new_runidrunidpost_load_pathsZ_has_mapper_entitiesZ_only_return_tupleslenr   Zsupports_single_entityr   listr   r   lightweight_named_tuplepartialsZ
_yield_perZ	fetchmanyZfetchallitemsinvokeZunique_list	ExceptioncloseZraise_from_cause)r   r   r   Zfilteredsingle_entityr   labelsZfetchZrowspath	post_loadr   errr   )r   r   r!   r    r"   r   r   	instances#   sP    

r3   zsqlalchemy.orm.queryTc          	      s  |j  r  j}zd_t|jdk}|rdt|jd jrZ fdd|D }nt|}nfddt|jD }g }dd |jD }t	
d|}	xh|D ]`}
t|
}xD|D ]<}|| d	k	rjt|| t||  i i d
||< qW ||	| qW t|S |_X d	S )z:Merge a result into this :class:`.Query` object's Session.Fr   r   c          	      s,   g | ]$}j t|t| i i d qS ))load
_recursive_resolve_conflict_map)_merger   instance_stateinstance_dict)r   instance)r4   sessionr   r   r   |   s   z merge_result.<locals>.<listcomp>c                s    g | ]\}}t | jr|qS r   )
isinstance_MapperEntity)r   ie)querylibr   r   r      s   c             S   s   g | ]
}|j qS r   )Z_label_name)r   r   r   r   r   r      s    r   N)r4   r5   r6   )r;   Z
_autoflush	autoflushr&   r   r<   r=   r'   	enumerater   r(   r7   r   r8   r9   appenditer)r@   r   iteratorr4   rA   r.   r   Zmapped_entitieskeysr!   r   Znewrowr>   r   )r4   r@   r;   r   merge_resultl   s<    




rG   c             C   s   | j |}|dk	rzt|}|jrv|tj@ s4tjS |tj@ sB|S y||| W n" t	j
k
rt   | |g dS X |S dS dS )zqLook up the given key in the given session's identity map,
    check the object for expired state if found.

    N)identity_mapgetr   r8   ZexpiredZSQL_OKZPASSIVE_NO_RESULTZRELATED_OBJECT_OKZ_load_expiredorm_excObjectDeletedErrorZ_remove_newly_deleted)r;   keyZpassiver:   stater   r   r   get_from_identity   s    


rN   c             C   s6   |dk	r|d }|d }nd }}t | |||||dS )z.Load the given identity key from the database.Nr   r   )refresh_statewith_for_updateonly_load_propsidentity_token)load_on_pk_identity)r   rL   rO   rP   rQ   ZidentrR   r   r   r   load_on_ident   s    
rT   c                s  |dkr|   }|  n|   }|dk	r|  }|j\} d|krnt fddt|j|D }	t||	}|	|dd}||_
t fddt||jD }
|
|_|dk	rd}||_n| jdk	rd}| j|_nd}|jt|||||d d|_y| S  tjk
r   dS X dS )z6Load the given primary key identity from the database.Nc                s"   g | ]\}}|d kr | j qS )N)rL   )r   colvalue)_get_paramsr   r   r      s   z'load_on_pk_identity.<locals>.<listcomp>TFc                s   g | ]\}} | j |fqS r   )rL   )r   Zid_valprimary_key)rW   r   r   r      s   )populate_existingversion_checkrQ   rO   rR   )Z_cloneZ_get_conditionZ_mapper_zero_get_clausesetr   rX   sql_utilZadapt_criterion_to_nullZ_adapt_clauseZ
_criteriondictZ_paramsZ_for_update_argZ_get_optionsboolZ	_order_byZonerJ   ZNoResultFound)r   Zprimary_key_identityrO   rP   rQ   rR   qmapperr[   ZnonesparamsrZ   r   )rW   r   rS      sL    





rS   c	             K   s   |r| |}
n|j}
i }|| jd| x<|
D ]4}|rD|j|krDq0|j| |||f|||d|	 q0W |d k	r||jk	r|r|j| }n|}|| d S )Nmemoized_setups)rQ   column_collectionZmemoized_populators)	Z_iterate_polymorphic_propertiesZ_polymorphic_propertiesr\   r   rL   Zsetuppolymorphic_oncolumnsrC   )r   ra   r   r0   adapterrd   Zwith_polymorphicrQ   polymorphic_discriminatorkwZpoly_propertiesquick_populatorsrV   Zpdr   r   r   _setup_entity_query  s0    

rk   c	                s$  
j  r fddD 
jtt
j}	dk	rR|	
fddD }	|jdt	}
x|	D ]}||
kr$|
| }|t
krd |j|jf n|tkrd |jd	f nfd} r j| }|dk	r||d	}|s||d	}|rd
 |j|f n||
|  qh||
|  qhW jjjjrZjj| n|jjjpr
jt
jjjt
jjjtjjjrjjj	tj tj!jj"j#j$j%sr|dk	rrd|jf}|jkr&j| j&dkr&
'j| j(d |}n
'd|}|rr||k	rrdksPt)t*||}t+,|j-||| t+.rjdkr
/nd
j0rt	j1nt	j 	
fdd}
j2r |s s t3|
||| }|S )z`Produce a mapper level row processor callable
       which processes rows into mapped instances.c                s   g | ]} j | qS r   )rf   )r   c)rg   r   r   r   h  s    z'_instance_processor.<locals>.<listcomp>Nc             3   s   | ]} j | V  qd S )N)Z_props)r   k)ra   r   r   r   p  s    z&_instance_processor.<locals>.<genexpr>rc   newexpireFquickloader))Zselectinload_polymorphicTZentitiesc       
   
      sJ  r,}|  }|}|jk}d}d}nt fddD f}|}|d k	r|}|}|jk}| }d}r|st||  nT|d rd S d}d}d}j }|}|}||_|_|_	
|| |sr|rss|_	|_t |||	|	 |r|rfrN|jj| r~
j|   nr~|jj| s|jrrr|| n|| rF|d n|j}|jk}|r|sd r,t |||	|}	|r,r |jj||	 |||	 rFjrF|d |S )NTFc                s   g | ]} | qS r   r   )r   column)r   r   r   r     s    z:_instance_processor.<locals>._instance.<locals>.<listcomp>r   eager)objr$   r   rI   _validate_version_idclass_managerZnew_instancerL   rR   
session_idZ_add_unpresentZload_options	load_path_populate_fullmanagerdispatchr4   r;   refreshZmodifiedZ_commitZ_commit_all	add_stateunloadedr)   _populate_partialZinvoke_all_eagers)
r   rM   r:   dict_isnewZcurrentloadloaded_instanceZidentitykeyr~   to_load)rg   r   identity_classrR   r9   r8   is_not_primary_keyload_evtrx   loaded_as_persistentra   rQ   persistent_evtpk_colsrY   
populatorsr1   propagate_optionsrefresh_evtrefresh_identity_keyrO   r$   rw   session_identity_maprZ   )r   r   	_instance  s    






z&_instance_processor.<locals>._instance)4rX   Z_identity_classcollectionsdefaultdictr'   Z	_prop_setintersectionrI   r   r
   r   rC   rL   Z_deferred_column_loaderr	   rf   Z_getterZcreate_row_processorr   r   Z_current_pathr0   r;   rH   rY   Zalways_refreshr_   rv   r{   r4   r|   r   r8   r9   Zhash_keyrZ   r$   rR   ZstrategyZ_should_selectin_loadZ
local_optsAssertionError_load_subclass_via_inPostLoadcallable_for_pathra   for_context_identity_key_from_stateallow_partial_pks
issupersetpolymorphic_map_decorate_polymorphic_switch)ra   r   r   r0   rg   rQ   rO   rh   _polymorphic_fromZpropsrj   ZproprU   getterZadapted_colrL   Zselectin_load_viaZ	callable_r   r   )rg   r   r   rR   r9   r8   r   r   rx   r   ra   rQ   r   r   rY   r   r1   r   r   r   rO   r$   rw   r   rZ   r   _instance_processorQ  s    






< 
r   c                sP   |j }t|jjdk|jr.||\ n|j\  fdd}|S )Nr   c                sb   | j }jf|j  f |j|d}|jr:|dd  || jjfdd|D d  d S )N)
cache_pathc             S   s   |   S )N)rY   )r`   r   r   r   <lambda>  s    z8_load_subclass_via_in.<locals>.do_load.<locals>.<lambda>c                s,   g | ]$\}} r|j d  d n|j d  qS )r   r   )rL   )r   rM   Z
load_attrs)zero_idxr   r   r     s   z:_load_subclass_via_in.<locals>.do_load.<locals>.<listcomp>)Zprimary_keys)	r   Z_with_lazyload_optionsZ_with_optionsparentZ_populate_existingZadd_criteriar;   rb   all)r   r0   statesZ	load_onlyZeffective_entityZ
orig_queryZq2)disable_opt
enable_optr`   r   r   r   do_load  s    

z&_load_subclass_via_in.<locals>.do_load)ra   r&   Zbase_mapperrX   Zis_aliased_classZ_subclass_load_via_inZ_subclass_load_via_in_mapper)r   r0   Zentityra   r   r   )r   r   r`   r   r   r     s    r   c	             C   s\  |r| j |_ x |d D ]\}	}
|
|||	< qW |rfxX|d D ]$\}	}||	d  |r<|j|	 q<W n&x$|d D ]\}	}|rp|j|	 qpW x |d D ]\}	}|||| qW x|d D ]\}	}|||| qW n||jkr4||_x(|d D ]\}	}
|	|kr|
|||	< qW xH|d D ]\}	}|||| qW n$x"|d D ]\}	}|||| q>W d S )Nrp   ro   rn   delayedexisting)r$   popexpired_attributesaddrx   )r   r   rM   r   r   rx   r   rY   r   rL   r   set_callable	populatorr   r   r   ry     s2    ry   c             C   s2  |s:| j | }x|d D ]\}	}
|	|kr|
||| qW n|}|| j |< x(|d D ]\}	}|	|krR||||	< qRW x8|d D ],\}	}|	|kr|||	d  |r||j|	 q|W x(|d D ]\}	}
|	|kr|
||| qW x(|d D ]\}	}
|	|kr|
||| qW x,|d D ] \}	}
|	|kr
|
||| q
W |S )Nr   rp   ro   rn   r   rs   )r)   r   r   r   )r   r   rM   r   r   rx   r~   r   r   rL   r   r   r   r   r   r   r     s2    


r   c          	   C   sd   | j }|d krd S |r |j| }| ||| j || kr`tdt|| ||| j || f d S )NzWInstance '%s' has version id '%s' which does not match database-loaded version id '%s'.)version_id_colrf   Z_get_state_attr_by_columnrJ   ZStaleDataErrorr   )ra   rM   r   r   rg   r   r   r   r   ru      s    


ru   c       	         s`   |d k	r|nj d kr S  r. j  fdd}t|fdd}|S )Nc                sT   yj |  }W n  tk
r.   td|  Y n"X |kr<d S t| dS d S )Nz*No such polymorphic_identity %r is defined)r   )r   KeyErrorr   r   )discriminatorZ
sub_mapper)rg   r   ra   r0   r   r   r   configure_subclass_mapper.  s    z?_decorate_polymorphic_switch.<locals>.configure_subclass_mapperc                s,   |  }|d k	r$| }|r$|| S  | S )Nr   )r   r   r   )instance_fnpolymorphic_instancesre   r   r   polymorphic_instanceD  s    z:_decorate_polymorphic_switch.<locals>.polymorphic_instance)re   rf   r   ZPopulateDict)	r   r   ra   r   r0   rh   rg   r   r   r   )rg   r   r   ra   r0   r   re   r   r   r     s    	

r   c               @   sP   e Zd ZdZdZdd Zdd Zdd Zed	d
 Z	edd Z
edd ZdS )r   z:Track loaders and states for "post load" operations.

    )loadersr   	load_keysc             C   s   i | _ t | _d | _d S )N)r   r   OrderedDictr   r   )selfr   r   r   __init__V  s    
zPostLoad.__init__c             C   s   || j |< d S )N)r   )r   rM   	overwriter   r   r   r}   [  s    zPostLoad.add_statec                sv   | j s
d S tj|}xP| j D ]B\} }}} fdd| j  D }|r"||||| jf|| q"W | j   d S )Nc                s&   g | ]\}}|j j r||fqS r   )rz   ra   Zisa)r   rM   r   )limit_to_mapperr   r   r   h  s   z#PostLoad.invoke.<locals>.<listcomp>)	r   r   ZPathRegistryZcoercer   valuesr*   r   clear)r   r   r0   tokenrq   argri   r   r   )r   r   r+   b  s    
zPostLoad.invokec             C   s$   |j |j}|d k	r |r ||_|S )N)r%   rI   r0   r   )clsr   r0   rQ   plr   r   r   r   p  s    zPostLoad.for_contextc             C   s   |j |jko||j|j  jkS )N)r0   r%   r   )r   r   r0   rL   r   r   r   path_existsw  s    zPostLoad.path_existsc       	      O   sD   |j |jkr|j|j  }nt  }|j|j < |||||f|j|< d S )N)r0   r%   r   r   )	r   r   r0   r   r   Zloader_callabler   ri   r   r   r   r   r   ~  s    zPostLoad.callable_for_pathN)__name__
__module____qualname____doc__	__slots__r   r}   r+   classmethodr   r   r   r   r   r   r   r   O  s   r   c       	         sB  |j }|stdt| t|j}d}|r>| j } j	r j
s ||}|dk	rt| t d|d||d}|dkr$|r|j}n< fdd jD }|j|rtdt|  |}t|r jrt|rtd	t| dS t| |||d
}|r>|dkr>t|dS )z4initiate a column-based attribute refresh operation.zQInstance %s is not bound to a Session; attribute refresh operation cannot proceedFN*)rQ   rO   c                s   g | ]} j | jqS r   )Z_columntopropertyrL   )r   rU   )ra   r   r   r     s    z*load_scalar_attributes.<locals>.<listcomp>z_Instance %s cannot be refreshed - it's not  persistent and does not contain a full primary key.zwInstance %s to be refreshed doesn't contain a full primary key - can't be refreshed (and shouldn't be expired, either).)rO   rQ   )r;   rJ   ZDetachedInstanceErrorr   r_   rL   r   ZattrsrF   ZinheritsZconcreteZ_optimized_get_statementrT   r   Zoptionsr   ZLoadZundeferZfrom_statementrX   r   sa_excZInvalidRequestErrorr   r
   issubsetr   r   r   Zwarn_limitedrK   )	ra   rM   Zattribute_namesr;   Zhas_keyr   Z	statementZidentity_keyZpk_attrsr   )ra   r   load_scalar_attributes  sR    




r   )T)NNN)NNNN)NNN)NNNN)%r   Z
__future__r   r    r   r   rJ   r   r   baser   r	   r   r
   r   r   Zsqlr]   Zcounterr#   r3   ZdependenciesrG   rN   rT   rS   rk   r   r   ry   r   ru   r   objectr   r   r   r   r   r   <module>   sN   I5
   
L  
/   
  - 9"4: