U
    cc                     @   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 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!ej"dddde dd@dd Z#d!d" Z$d#d#d#d#d$ej%ej%fd%d&Z&d#d#d#d#d#d$ej%ej%fd'd(Z'dAd)d*Z(dBd+d,Z)d-d. Z*dCd/d0Z+d1d2 Z,d3d4 Z-d5d6 Z.d7d8 Z/d9d: Z0G d;d< d<e1Z2d=d> Z3d#S )Dzprivate 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_import   )
attributes)exc)path_registry)strategy_options)_DEFER_FOR_STATE)_RAISE_FOR_STATE)_SET_DEFERRED_EXPIRED)	_none_set)	state_str   )future)util)result_tuple)ChunkedIteratorResult)FrozenResult)SimpleResultMetaData)LABEL_STYLE_TABLENAME_PLUS_COL)SelectStatec                    s  t  _i _j}|j}jj o<t|jdko<|jd j	zFt
tfddjjD  \}}jrjsxjrtdW n0 tk
r   t    W 5 Q R X Y nX dd  dd	 jjr fd
djjD }n fddjjD }t|||d}fdd}jddrJt
|dfdd}t||jjd}	|	jt|d|	_jjrdd }
d|
f|	_ jr|	j |	S )a  Return a :class:`.Result` given an ORM query context.

    :param cursor: a :class:`.CursorResult`, generated by a statement
     which came from :class:`.ORMCompileState`

    :param context: a :class:`.QueryContext` object

    :return: a :class:`.Result` object representing ORM results

    .. versionchanged:: 1.4 The instances() function now uses
       :class:`.Result` objects and has an all new interface.

    r   r   c                    s   g | ]}|  qS  )Zrow_processor).0query_entity)contextcursorr   :/tmp/pip-unpacked-wheel-8u86ls_i/sqlalchemy/orm/loading.py
<listcomp>E   s   zinstances.<locals>.<listcomp>zCan't use yield_per with eager loaders that require uniquing or row buffering, e.g. joinedload() against collections or subqueryload().  Consider the selectinload() strategy for better flexibility in loading objects.c                 S   s   t dd S )Nz@Can't use the ORM yield_per feature in conjunction with unique()sa_excInvalidRequestError)entryr   r   r   
_no_unique[   s    zinstances.<locals>._no_uniquec                    s    fdd}|S )Nc                    s   t d  d S )NzkCan't apply uniqueness to row tuple containing value of type %r; this datatype produces non-hashable valuesr   objdatatyper   r   goa   s
    z,instances.<locals>._not_hashable.<locals>.gor   )r%   r&   r   r$   r   _not_hashable`   s    z instances.<locals>._not_hashablec                    s0   g | ](}j r n|js$|js$|jr(tnd qS N)	yield_peruse_id_for_hash_non_hashable_valueZ_null_column_typeidr   ent)r!   r   r   r   r   k   s   
c                    s<   g | ]4}j r n$|js*|jr*|jjn|jr4tnd qS r(   )r)   r*   r+   columntyper,   r-   )r!   r'   r   r   r   r   x   s   )Z_unique_filtersc                 3   s   | }i _ |r |}|s(qn }rHd   fdd|D }nfdd|D }j D ]\}}|| qd|V  |s qq d S )Nr   c                    s   g | ]} |qS r   r   )r   rowprocr   r   r      s     z-instances.<locals>.chunks.<locals>.<listcomp>c                    s"   g | ] t  fd dD qS )c                    s   g | ]}| qS r   r   )r   r3   r1   r   r   r      s     z8instances.<locals>.chunks.<locals>.<listcomp>.<listcomp>)tuple)r   )processr4   r   r      s    )partialsZ	fetchmanyZ_raw_all_rowspost_load_pathsitemsinvoke)sizer)   fetchZrowspath	post_load)r   r   r6   single_entityr2   r   chunks   s$    

zinstances.<locals>.chunksZprebuffer_rowsFNc                    s   t  S r(   )iter)r;   )_prebufferedr   r   r@      s    )Zsource_supports_scalarsrawZdynamic_yield_per)filteredZis_single_entityc                 S   s   t dd S )Nz~The unique() method must be invoked on this Result, as it contains results that include joined eager loads against collectionsr   r"   r   r   r   require_unique   s    z!instances.<locals>.require_unique)!
_new_runidrunidr8   compile_stateZ_has_mapper_entitiesload_optionsZ_only_return_tupleslen	_entitiesZsupports_single_entitylistzipr)   Zloaders_require_bufferingZloaders_require_uniquingr   r   	Exceptionr   Zsafe_reraisecloseZ_legacy_uniquingr   execution_optionsgetr   r   Z_is_server_side_attributesuniondictZmulti_row_eager_loadersZ_unique_filter_state)r   r   rH   rD   labelsextraZunique_filtersZrow_metadatar@   resultrE   r   )r!   r'   rB   r   r   r6   r?   r   	instances(   s|    


	


  


rX   zsqlalchemy.orm.contextTc              	      s   t jj |r|    jj|dd}| j}zd| _ fddt|jD }dd |jD }t	|dd |jD }g }	|
 D ]T}
|D ]<}|
| dk	r| jt|
| t|
| |i i d|
|< q|	||
 q|||	W S || _X dS )	az  Merge a :class:`_engine.FrozenResult` back into a :class:`_orm.Session`,
    returning a new :class:`_engine.Result` object with :term:`persistent`
    objects.

    See the section :ref:`do_orm_execute_re_executing` for an example.

    .. seealso::

        :ref:`do_orm_execute_re_executing`

        :meth:`_engine.Result.freeze`

        :class:`_engine.FrozenResult`

    Flegacyc                    s    g | ]\}}t | jr|qS r   
isinstance_MapperEntityr   iequerycontextr   r   r      s   z'merge_frozen_result.<locals>.<listcomp>c                 S   s   g | ]
}|j qS r   Z_label_namer-   r   r   r   r      s     c                 S   s   g | ]
}|j qS r   Z_extra_entitiesr-   r   r   r   r      s     Nload
_recursiveZ_resolve_conflict_map)r   	preloadedorm_context
_autoflushORMSelectCompileState_create_entities_collection	autoflush	enumeraterK   r   Zrewrite_rows_merger   instance_stateinstance_dictappendZwith_new_rows)session	statementfrozen_resultrf   ctxrm   mapped_entitieskeyskeyed_tuplerW   newrowr_   r   ra   r   merge_frozen_result   s@     
 r{   z:func:`_orm.merge_result`zyThe function as well as the method on :class:`_orm.Query` is superseded by the :func:`_orm.merge_frozen_result` function.)alternativeZbecomes_legacyc              	      sv  t jj| j r  t|tr4|}t|j}nd}j	j
| dd}j}zd_| ojt|jdk}|rt|jd jr fdd|D }nt|}nfd	dt|jD }g }d
d |jD }	t|	dd |jD }
|D ]\}t|}|D ]<}|| dk	rjt|| t||  i i d||< q||
| q|rZ||W S t|W S W 5 |_X dS )zMerge a result into the given :class:`.Query` object's Session.

    See :meth:`_orm.Query.merge_result` for top-level documentation on this
    function.

    NTrY   Fr   r   c              	      s,   g | ]$}j t|t| i i d qS )re   )ro   r   rp   rq   )r   instance)rf   rs   r   r   r   4  s   z merge_result.<locals>.<listcomp>c                    s    g | ]\}}t | jr|qS r   r[   r^   ra   r   r   r   A  s   c                 S   s   g | ]
}|j qS r   rc   r-   r   r   r   r   G  s     c                 S   s   g | ]
}|j qS r   rd   r-   r   r   r   r   J  s     re   )r   rh   ri   rs   rj   r\   r   rA   datark   rl   rm   rJ   rK   r]   rL   rn   r   ro   r   rp   rq   rr   Z	with_data)queryiteratorrf   ru   rv   rm   r?   rW   rw   rx   ry   r1   rz   r_   r   )rf   rb   rs   r   merge_result  s^    
 

 r   c                 C   s   | j |}|dk	rt|}|jr6|j|s6tjS |jr|tj	@ sLtj
S |tj@ sZ|S z||| W n$ tjk
r   | |g Y 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_maprQ   r   rp   inheritsmapperisaZPASSIVE_CLASS_MISMATCHZexpiredZSQL_OKZPASSIVE_NO_RESULTZRELATED_OBJECT_OKZ_load_expiredorm_excObjectDeletedErrorZ_remove_newly_deleted)rs   r   keypassiver}   stater   r   r   get_from_identityb  s"    


r   NFc
                 C   s@   |dk	r|d }
|d }nd }
}t | ||
||||||||	dS )z.Load the given identity key from the database.Nr   r   )rI   refresh_statewith_for_updateonly_load_propsidentity_tokenno_autoflushbind_argumentsrP   )load_on_pk_identity)rs   rt   r   rI   r   r   r   r   r   rP   identr   r   r   r   load_on_ident  s"    
r   c                    s  |}|  }|jrtddlm}m} |dkr4|j}|jtj	krH|j
}n|j}|dk	r|jd }|j\} d|krt fddt|j|D }t||}t|t|krtd t|dd	if|_t fd
dt||jD }nd}|dk	rd	}||_n|jdk	rd	}|j|_nd}|rL|jrL|d|jji7 }|j|j }t||||||d\}}||_d|_|r|ddi7 }tj |
d|i}
| j!|||
|	d" # }z
|$ W S  t%j&k
r   Y dS X dS )z6Load the given primary key identity from the database.r   )QueryContextORMCompileStateNZplugin_subjectc                    s"   g | ]\}}|d kr | j qS r(   r   )r   colvalueZ_get_paramsr   r   r     s   z'load_on_pk_identity.<locals>.<listcomp>zofully NULL primary key identity cannot load any object.  This condition may raise an error in a future release.Z
_orm_adaptTc                    s   g | ]\}} | j |fqS r   r   )r   Zid_valprimary_keyr   r   r   r     s   F_current_path)version_checkr   r   r   rj   Z_sa_orm_load_options)paramsrP   r   )'Z_cloneZ_is_lambda_elementAssertionErrorr   r   r   Zdefault_load_options_compile_optionsr   Zdefault_select_compile_optionsdefault_compile_optionsZ_propagate_attrs_get_clausesetrM   r   sql_utilZadapt_criterion_to_nullrJ   r   warnZ_deep_annotateZ_where_criteriarT   Z_for_update_argrI   	load_pathparentoptions_set_get_optionsZ	_order_by
EMPTY_DICTZ
merge_withexecuteuniquescalarsZoner   ZNoResultFound)rs   rt   Zprimary_key_identityrI   r   r   r   r   r   r   rP   r   qr   r   compile_optionsr   r   Znonesr   r   Znew_compile_optionsrW   r   r   r   r     s    



 

 	


 
r   c           	      C   sp   i }i }|r||d< |r ||d< |r4||d< d|d< |rDt ||d< |rP||d< |r\||7 }|rh| |7 } | |fS )NZ_version_checkZ_populate_existingZ_refresh_stateTZ_for_refresh_stateZ_only_load_propsZ_refresh_identity_token)	frozenset)	Zcompile_optZload_optpopulate_existingr   r   r   r   r   rI   r   r   r   r   "  s$    
r   c	                 K   s   |r| |}
n|j}
i }|| jd| |oBt|dkoB|d j}|
D ]6}|r\|j|kr\qH|j| |||f||||d|	 qH|d k	r||jk	r|r|j	| }n|}|
| d S )Nmemoized_setupsr   )r   column_collectionZmemoized_populatorscheck_for_adapt)Z_iterate_polymorphic_propertiesZ_polymorphic_propertiesr   r   rJ   is_aliased_classr   setuppolymorphic_oncolumnsrr   )rH   r   r   r=   adapterr   Zwith_polymorphicr   polymorphic_discriminatorkwZpoly_propertiesquick_populatorsr   r   pdr   r   r   _setup_entity_queryB  s@    	r   c                 C   s   t dt| f  d S )Nam  Loading context for %s has changed within a load/refresh handler, suggesting a row refresh operation took place. If this event handler is expected to be emitting row refresh operations within an existing load or refresh operation, set restore_load_context=True when establishing the listener to ensure the context remains unchanged when the event handler completes.)r   r   r   )r   r   r   r   _warn_for_runid_changed|  s
    r   c
                    s@  
j j}
d
f}||
j|d}|dkrĈ
j}dk	rT|
fddD }|jdt}g }g g g g g g g d}dkr
j} r fdd|D }||nd||d	}|D ]}||kr|| }|t	kr|d
 
|j|jf n|tkr|d 
|jdf n|tkr8|d
 
|j|jf nnd} rb j| }|dk	rb||d}|st||d}|r|d 
|j|f n|| |
| | q|
| q||
j|| |d }dd | D |d D ]}|| |
|  qjjjjr"jj| n|jjjp:
jt
jjjt
jjj tjjj!rvjjj!	tj"tj#jj$j%j&j'r҈
j(}|dk	rΈ r j| }||ndsp|	dk	rpd|jf}|jkr$j| j)dkr$
*j| j+d |	}n
*d|	}|rp||	k	rpdksNt,t-||}t./|j0||| t.1rjdkr
2nd|d 
j3rtj4ntj	
fdd}
j5r<|	s<s<fdd}t6|| 
||| |	}|S )z]Produce a mapper level row processor callable
    which processes rows into mapped instances.gettersNc                 3   s   | ]} j | V  qd S r(   )Z_props)r   kr   r   r   	<genexpr>  s    z&_instance_processor.<locals>.<genexpr>r   )newquickdeferredexpiredelayedexistingeagerc                    s   g | ]} j | qS r   )r   )r   c)r   r   r   r     s     z'_instance_processor.<locals>.<listcomp>)cached_populatorstodoprimary_key_getterr   r   Fr   r   c                 S   s   i | ]\}}|t |qS r   )rL   )r   r   r   r   r   r   
<dictcomp>  s      z'_instance_processor.<locals>.<dictcomp>r   loader))Zselectinload_polymorphicTentitiesr   c              
      s  r,}|  }|}|jk}d}d}n| f}|}|d k	r|}|}|jk}| }d}rr|st	|||  nT|d rd S d}d}d}	j }|}|}||_|_|_	|| }|krd}|s|r
|rs|s|_
|_t | |||||	 |r|j}	|rrn|jj|  |j|	krnt| r j| |j|	krt| n,r|jj| 
 |jkrt| |s|jrr
r||
 n|| r|d n|j}
| jk}|r0|
s0d rt | ||||
}|rr~|j}	|jj| | |j|	kr~t| ||| r jr|d |S )NTFr   r   )r#   rG   rQ   _validate_version_idclass_managerZnew_instancer   r   
session_idZ_add_unpresentrI   r   _populate_fullmanagerdispatchrf   r   rs   refreshmodifiedZ_commitZ_commit_all	add_stateunloadedr7   _populate_partialZinvoke_all_eagers)r1   r   r}   dict_isnewZcurrentloadloaded_instanceidentitykeyZeffective_populate_existingZexisting_runidr   to_load)r   identity_classr   rq   rp   is_not_primary_keyload_evtr   loaded_as_persistentr   r   persistent_evtr   
populatorsr>   r   propagated_loader_optionsrefresh_evtrefresh_identity_keyr   rG   r   session_identity_mapr   version_id_getterr   r   	_instances  s    


    	


  
z&_instance_processor.<locals>._instancec                    s&    | f}|d s|S d S d S )Nr   r   )r1   r   )r   r   r   r   r   r   ensure_no_pk  s    z)_instance_processor.<locals>.ensure_no_pk)7Z_identity_classrH   rQ   r   Z	_prop_setintersectionr   r   Z_tuple_getterr   rr   r   Z_deferred_column_loaderr
   r	   Z_raise_column_loaderr   _getterZcreate_row_processorr   r9   r   current_pathr=   rs   r   r   Zalways_refreshboolr   r   rf   r   r   rp   rq   Zhash_keyrG   r   r   version_id_colZstrategyZ_should_selectin_loadZ
local_optsr   _load_subclass_via_inPostLoadcallable_for_pathr   for_context_identity_key_from_stateallow_partial_pks
issupersetpolymorphic_map_decorate_polymorphic_switch)r   r   r   rW   r=   r   r   r   r   _polymorphic_fromrH   Z
getter_keyr   propsr   r   r   Zpk_colspropr   getterZadapted_colr   r   Zselectin_load_viaZ	callable_r   r   r   )r   r   r   r   rq   rp   r   r   r   r   r   r   r   r   r   r>   r   r   r   r   r   rG   r   r   r   r   r   _instance_processor  s4   
  







      



 	
< "r  c                    sP   |j }t|jjdk|jr.||\ n|j\  fdd}|S )Nr   c                    s   | j }f|j  f }j| }| jj|_| jd|ji7  _| jrR|jdd}| j	
|tfdd|D d    d S )Nr   T)r   c                    s,   g | ]$\}} r|j d  d n|j d  qS )r   r   r   )r   r   Z
load_attrs)zero_idxr   r   r   J  s   z:_load_subclass_via_in.<locals>.do_load.<locals>.<listcomp>)Zprimary_keys)r   Z_with_optionsr   rH   r   r   r   r   rP   rs   r   rT   r   r   all)r   r=   states	load_onlyZeffective_entityZ
orig_queryr   Zq2Zdisable_optZ
enable_optr   r  r   r   do_load;  s    


z&_load_subclass_via_in.<locals>.do_load)r   rJ   Zbase_mapperr   r   Z_subclass_load_via_inZ_subclass_load_via_in_mapper)r   r=   entityr   r  r   r  r   r   1  s    r   c	                 C   s:  |r| j |_ |d D ]\}	}
|
|||	< q|r^|d D ]$\}	}||	d  |r6|j|	 q6n"|d D ]\}	}|rf|j|	 qf|d D ]\}	}|||| q|d D ]\}	}|||| qnx||jkr||_|d D ]\}	}
|	|kr|
|||	< q|d D ]\}	}|||| qn |d D ]\}	}|||| qd S )Nr   r   r   r   r   )rG   popexpired_attributesaddr   )r   r1   r   r   r   r   r   r   r   r   r  set_callable	populatorr   r   r   r   T  s2    r   c                 C   s  |s6| j | }|d D ]\}	}
|	|kr|
||| qn|}|| j |< |d D ]\}	}|	|krL||||	< qL|d D ],\}	}|	|krr||	d  |rr|j|	 qr|d D ]\}	}
|	|kr|
||| q|d D ]\}	}
|	|kr|
||| q|d D ]\}	}
|	|kr|
||| q|S )Nr   r   r   r   r   r   )r7   r
  r  r  )r   r1   r   r   r   r   r   r   r   r   r  r  r  r   r   r   r     s2    

r   c              	   C   sD   |  ||| 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'.)Z_get_state_attr_by_columnr   r   ZStaleDataErrorr   )r   r   r   r1   r  r   r   r   r     s&        r   c	                    sr   |d k	r|nj d kr S  r. j  	
fdd}	t|	
fdd}
|
S )Nc              	      sd   zj |  }W n  tk
r.   td|  Y n2X |kr<d S |sJdS t| dS d S )Nz*No such polymorphic_identity %r is definedF)r   )r   KeyErrorr   r   r  )discriminatorZ
sub_mapper)r   r   r   r=   r   rW   r   r   configure_subclass_mapper  s&    

z?_decorate_polymorphic_switch.<locals>.configure_subclass_mapperc                    s   | }|d k	rf| }|r$|| S |dkr\ | }|rVt d|j| f qdd S q| S n$ | }|rt d|f nd S d S )NFzRow with identity key %s can't be loaded into an object; the polymorphic discriminator column '%s' refers to %s, which is not a sub-mapper of the requested %szjRow with identity key %s can't be loaded into an object; the polymorphic discriminator column '%s' is NULL)r   r   r   )r1   r  r   r   )r   r  instance_fnr   polymorphic_instancesr   r   r   polymorphic_instance  s6    
z:_decorate_polymorphic_switch.<locals>.polymorphic_instance)r   r   r   ZPopulateDictr   )r  r   r   r   rW   r=   r   r   r   r  r  r   )r   r   r   r  r  r   r=   r  r   r   rW   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   z4Track loaders and states for "post load" operations.)loadersr  	load_keysc                 C   s   i | _ t | _d | _d S r(   )r  r   OrderedDictr  r  )selfr   r   r   __init__   s    
zPostLoad.__init__c                 C   s   || j |< d S r(   )r  )r  r   	overwriter   r   r   r   %  s    zPostLoad.add_statec                    sr   | j s
d S tj|}| j D ]B\} }}} fdd| j  D }|r ||||| jf|| q | j   d S )Nc                    s&   g | ]\}}|j j r||fqS r   )r   r   r   )r   r   r  limit_to_mapperr   r   r   1  s   z#PostLoad.invoke.<locals>.<listcomp>)	r  r   ZPathRegistryZcoercer  valuesr9   r  clear)r  r   r=   tokenr   argr   r  r   r  r   r:   ,  s    
zPostLoad.invokec                 C   s$   |j |j}|d k	r |r ||_|S r(   )r8   rQ   r=   r  )clsr   r=   r   plr   r   r   r   :  s    zPostLoad.for_contextc                 C   s   |j |jko||j|j  jkS r(   )r=   r8   r  )r  r   r=   r   r   r   r   path_existsA  s    zPostLoad.path_existsc           	      O   sD   |j |jkr|j|j  }nt  }|j|j < |||||f|j|< d S r(   )r=   r8   r   r  )	r!  r   r=   r  r  Zloader_callabler   r   r"  r   r   r   r   H  s    zPostLoad.callable_for_pathN)__name__
__module____qualname____doc__	__slots__r  r   r:   classmethodr   r#  r   r   r   r   r   r     s   

r   c                    st  |j }|stdt| t|j}d}t|tj@ p>|j j}|rT|	 j
 } jr js ||}|dk	rddlm}	 |	 |t d}
t||
d|||d}|dkrV|r|j}n< fdd	 jD }|j	|rtd
t|  |}t|r jr"t|r6t dt| dS t|t!" #t$||||d}|rp|dkrpt%|dS )z4initiate a column-based attribute refresh operation.zQInstance %s is not bound to a Session; attribute refresh operation cannot proceedFNr   )FromStatement*)r   r   r   c                    s   g | ]} j | jqS r   )Z_columntopropertyr   )r   r   r   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).)r   r   r   )&rs   r   ZDetachedInstanceErrorr   r   r   r   ZNO_AUTOFLUSHZ
autocommitr   attrsrx   r   ZconcreteZ_optimized_get_statementr   r*  r   r   LoadZundeferr   r   r  r   r   r   r   issubsetr   r   r   Zwarn_limitedr   selectZset_label_styler   r   )r   r   Zattribute_namesr   rs   Zhas_keyrW   r   rt   r*  ZstmtZidentity_keyZpk_attrsr   r   r   load_scalar_attributesS  s    

	
	



r0  )T)T)NNNNN)NNN)NNNN)4r'  
__future__r    r   r   r   r   r   baser   r	   r
   r   r   r   r   r   Zenginer   Zengine.resultr   r   r   Zsqlr   Zsql.selectabler   r   counterrF   rX   Zpreload_moduler{   Zdeprecated_20r   r   r   r   r   r   r   r   r  r   r   r   r   r   objectr   r0  r   r   r   r   <module>   s    (;P&
&
     
'   
:    
   ,#:"Y8