a
    [g                    @  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 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m0Z0 dd)l1m2Z2 e
rndd*l3m4Z4 dd+l3m5Z5 dd,l3m6Z6 dd-l7m8Z8 dd.l9m:Z: dd/l9m;Z; dd0l9m<Z< dd1l9m=Z= dd2l>m?Z? dd3lm@Z@ dd4lmAZA dd5lBmCZC ed6eDd7ZEe	d8d8d9d:d;d<d=d=d=d>d?d@dA	dBdCZFe	d8d8d9d:d;d<d=d=d=dDd?dEdA	dFdCZFdGdGd9d:d;d<d=d=d=dDd?dHdA	dIdCZFe	d8dJdKdLd;d<d=d=d>d=d@dMdNdOZGe	d8dJdKdLd;d<d=d=dPd=dQdMdRdOZGdGdJdKdLd;d<d=d=dPd=dSdMdTdOZGdUdV ZHG dWdX dXeZIG dYdZ dZeIZJe*Kd[d\G d]d^ d^eIe.ZLe*Kd[d_G d`da daeJe/ZMe*Kd[dbG dcdd ddeJe-ZNdGS )ezoadditional ORM persistence classes related to "bulk" operations,
specifically outside of the flush() process.

    )annotations)Any)cast)Dict)Iterable)Optional)overload)TYPE_CHECKING)TypeVar)Union   )
attributes)context)	evaluator)exc)loading)persistence)NO_VALUE)AbstractORMCompileState)FromStatement)ORMFromStatementCompileState)QueryContext   )util)Dialect)result)	coercions)dml)
expression)roles)select)sqltypes)_entity_namespace_key)CompileState)Options)DeleteDMLState)InsertDMLState)UpdateDMLState)
EMPTY_DICT)Literal)DMLStrategyArgument)OrmExecuteOptionsParameter)SynchronizeSessionArgument)Mapper)_BindArguments)ORMExecuteState)Session)SessionTransaction)InstanceState)
Connection)cursor)_CoreAnyExecuteParams_O)bound.)use_orm_insert_stmtexecution_optionsz
Mapper[_O]z<Union[Iterable[InstanceState[_O]], Iterable[Dict[str, Any]]]r1   boolzLiteral[None]z$Optional[OrmExecuteOptionsParameter]None)	mappermappingssession_transactionisstatesreturn_defaultsrender_nullsr8   r9   returnc                C  s   d S N r<   r=   r>   r?   r@   rA   r8   r9   rD   rD   m/var/www/html/cobodadashboardai.evdpl.com/venv/lib/python3.9/site-packages/sqlalchemy/orm/bulk_persistence.py_bulk_insertJ   s    rG   zOptional[dml.Insert]zcursor.CursorResult[Any]c                C  s   d S rC   rD   rE   rD   rD   rF   rG   X   s    Nz"Optional[cursor.CursorResult[Any]]c                  s  j }|jjrtd|rbtr0tttt  |rRdd D }	dd |	D qdd D n@tr|ttt	t
tf  |rtndd D t || d }
fdd|j D }|rd}nt|d	krd}nd
}|D ]\}}|d urfdd| D nd} fddtj| fddD d|||dD }tj|d ||||||d}|d ur|jr|
d u r|}
q|jr|sJ |
|}
q|r|rj}dd jD }|	D ](\}|tfdd|D d f|_q|d ur|
d usJ |
S d S )NzJconnection_callable / per-instance sharding not supported in bulk_insert()c                 S  s   g | ]}||j fqS rD   dict.0staterD   rD   rF   
<listcomp>       z _bulk_insert.<locals>.<listcomp>c                 S  s   g | ]\}}|qS rD   rD   )rK   rL   dict_rD   rD   rF   rM      rN   c                 S  s   g | ]
}|j qS rD   rH   rJ   rD   rD   rF   rM      rN   c                 S  s   g | ]}t |qS rD   rH   rK   mrD   rD   rF   rM      rN   c                   s"   g | ]\}}| j v r||fqS rD   )_pks_by_table)rK   tablempr<   rD   rF   rM      s   
Tr   Fc                   s    g | ]}|j  d  v r|j qS r   keyrK   br=   rD   rF   rM      s   rD   c           	   	   3  s2   | ]*\}}}}}}}}d || |||fV  qd S rC   rD   )	rK   rL   Z
state_dictparamsrT   connZvalue_paramsZhas_all_pksZhas_all_defaults
connectionr<   rD   rF   	<genexpr>   s$   z_bulk_insert.<locals>.<genexpr>c                 3  s   | ]}d | fV  qd S rC   rD   rK   mappingr^   rD   rF   r`      rN   )bulkr@   rA   include_bulk_keys)bookkeepingr8   r9   c                 S  s   g | ]
}|j qS rD   rW   )rK   prD   rD   rF   rM      rN   c                   s   g | ]} | qS rD   rD   rK   rX   )rO   rD   rF   rM      rN   )base_mappersessionconnection_callableNotImplementedErrorr	   r   r   r2   r6   r   strr   list_expand_compositesr_   _sorted_tablesitemslen_get_embedded_bindparamsr   Z_collect_insert_commandsZ_emit_insert_statements
_returningZreturns_rowsZsplice_horizontallyZ_identity_class_identity_key_propstuplerX   )r<   r=   r>   r?   r@   rA   r8   r9   rh   statesZreturn_resultZmappers_to_runre   rS   super_mapperextra_bp_namesrecordsr   Zidentity_clsZidentity_propsrL   rD   )r_   rO   r<   r=   rF   rG   f   s    








T)use_orm_update_stmtenable_check_rowcountMapper[Any])r<   r=   r>   r?   update_changed_onlyrz   r{   rB   c                C  s   d S rC   rD   r<   r=   r>   r?   r}   rz   r{   rD   rD   rF   _bulk_update   s    
r   zOptional[dml.Update]z_result.Result[Any]c                C  s   d S rC   rD   r~   rD   rD   rF   r     s    
zOptional[_result.Result[Any]]c                  s0  j }jjr"jjhfdd |r\|rL fddD qtdd D ndd D t |jjrtd|	||d urfdd|
 D nd	}|j D ]^\}	}
|
r|	jvrqtjd |	fd
dD d||d}tj|d |
|	|d||d q|d ur,t S d S )Nc                   s    fdd j  D S )Nc                   s(   i | ] \}}|j v s| v r||qS rD   )Zcommitted_staterK   kv)search_keysrL   rD   rF   
<dictcomp>)  s   z7_bulk_update.<locals>._changed_dict.<locals>.<dictcomp>)rI   rp   )r<   rL   )r   )rL   rF   _changed_dict(  s    z#_bulk_update.<locals>._changed_dictc                   s   g | ]} |qS rD   rD   rJ   )r   r<   rD   rF   rM   1  rN   z _bulk_update.<locals>.<listcomp>c                 S  s   g | ]
}|j qS rD   rH   rJ   rD   rD   rF   rM   3  rN   c                 S  s   g | ]}t |qS rD   rH   rP   rD   rD   rF   rM   5  rN   zJconnection_callable / per-instance sharding not supported in bulk_update()c                   s    g | ]}|j  d  v r|j qS rV   rW   rY   r[   rD   rF   rM   C  s   rD   c                 3  s.   | ]&}d | j r |j j nd fV  qd S rC   )_version_id_proprX   ra   r^   rD   rF   r`   S  s   z_bulk_update.<locals>.<genexpr>T)rc   rz   rd   F)re   rz   r{   )rh   Z_primary_key_propkeysr   rX   unionrn   ri   rj   rk   r_   rr   ro   rp   isarR   r   Z_collect_update_commandsZ_emit_update_statements_resultnull_result)r<   r=   r>   r?   r}   rz   r{   rh   rx   rS   rw   ry   rD   )r   r_   r<   r=   r   rF   r     s^    





c                   sV   | j   sd S t  } fdd|D }|D ] }||D ]}|| | q>q0d S )Nc                   s   i | ]}| |   qS rD   )Z)_populate_composite_bulk_save_mappings_fnrg   Zcomposite_attrsrD   rF   r   z  s   z&_expand_composites.<locals>.<dictcomp>)Z
compositessetkeysintersection)r<   r=   Zcomposite_keysZ
populatorsrb   rX   rD   r   rF   rn   t  s    
rn   c                   @  st   e Zd ZU dZdZded< edd Zedd Zed	d
 Z	edd Z
edd ZddddZedd ZdS )ORMDMLStateTNz&Optional[ORMFromStatementCompileState]from_statement_ctxc                 c  s   t j}|D ]\}}ttj|}t|trt||t	d}|t	u rrttj||rhtjtj
|t ddn|fV  q|||||E d H  q
d|jv r|j}	t|	d |	d }
|||
||E d H  q
||s|ntjtj
|t ddfV  q
d S )N)defaultT)type_Zis_crudZentity_namespace	proxy_key)r'   _get_crud_kv_pairsr   expectr   ZDMLColumnRole
isinstancerl   r"   r   ExpressionElementRoler!   ZNullTypeZ_bulk_update_tuples_annotations)clsr<   	statementkv_iteratorneeds_to_be_cacheableZcore_get_crud_kv_pairsr   r   descZk_annoattrrD   rD   rF   _get_orm_crud_kv_pairs  sR    

z"ORMDMLState._get_orm_crud_kv_pairsc                   s6   j d rjs t|S  fdd|D S )Nplugin_subjectc              	     s&   g | ]}t  j| d qS )F)rI   r   r<   rp   )rK   Z
value_dictr   r   r   rD   rF   rM     s   z8ORMDMLState._get_multi_crud_kv_pairs.<locals>.<listcomp>)_propagate_attrsr<   r'   _get_multi_crud_kv_pairs)r   r   r   rD   r   rF   r     s    

z$ORMDMLState._get_multi_crud_kv_pairsc                 C  sD   |sJ d|j d }|r |js.t|||S t| |j|||S )Nz0no test coverage for needs_to_be_cacheable=Falser   )r   r<   r'   r   rm   r   )r   r   r   r   r   rD   rD   rF   r     s"    

zORMDMLState._get_crud_kv_pairsc                 C  s@   |j jd }|j}|jr |j}n|jj}||j|j|j|jdS )Nparententity)nametypeexprentityrS   )	rS   r   r<   is_aliased_classr   class___name__r   local_table)r   r   ext_infor<   Z_label_namerD   rD   rF   get_entity_description  s    z"ORMDMLState.get_entity_descriptionc                   s2   dd dd   fddfdd|j D D S )Nc                 S  s   | j dd S )Nr   )r   get)crD   rD   rF   _ent_for_col  s    zCORMDMLState.get_returning_column_descriptions.<locals>._ent_for_colc                 S  s4   |d u r| S | j dd }|s"| S t|j|| S d S )Nr   )r   r   getattrr   )r   entr   rD   rD   rF   _attr_for_col  s    zDORMDMLState.get_returning_column_descriptions.<locals>._attr_for_colc                   s.   g | ]&\}}|j |j |||j|jd qS ))r   r   r   aliasedr   )rX   r   r   r   )rK   r   r   )r   rD   rF   rM     s   zAORMDMLState.get_returning_column_descriptions.<locals>.<listcomp>c                   s   g | ]}| |fqS rD   rD   rK   r   )r   rD   rF   rM     s   )Z_all_selected_columns)r   r   rD   )r   r   rF   !get_returning_column_descriptions  s    	

z-ORMDMLState.get_returning_column_descriptions)use_supplemental_colsc          	      C  s   |j rt|j |dd}|jf i |j}|j|j }|| _t|| | _	}|
| | }d|_ dd |jD }|s||j |r|j|jd|i}n
|j| }|S )al  establish ORM column handlers for an INSERT, UPDATE, or DELETE
        which uses explicit returning().

        called within compilation level create_for_statement.

        The _return_orm_returning() method then receives the Result
        after the statement was executed, and applies ORM loading to the
        state that we first established here.

        F)Z_adapt_on_namesrD   c                 S  s   g | ]}|d ur|qS rC   rD   r   rD   rD   rF   rM   8  rN   z4ORMDMLState._setup_orm_returning.<locals>.<listcomp>Zsupplemental_cols)rs   r   r9   _execution_optionsoptions_with_optionsselect_statementr   create_for_statementr   Z!setup_dml_returning_compile_stateZ	_generateZprimary_columnsextendprimary_keyr@   Z	returning)	selfcompilerorm_level_statementZdml_level_statement
dml_mapperr   fsZfscZcols_to_returnrD   rD   rF   _setup_orm_returning  s6    

z ORMDMLState._setup_orm_returningc              	   C  sZ   |j }|jj}|jrR|jjjsR|dtj}	t|j|j	||||	||}
t
||
S |S d S )N_sa_orm_load_options)r   compiledcompile_stater   compile_options_is_starr   r   default_load_optionsr   r   Z	instances)r   ri   r   r\   r9   bind_argumentsr   Zexecution_contextr   load_optionsZquerycontextrD   rD   rF   _return_orm_returningV  s*    

z!ORMDMLState._return_orm_returning)r   
__module____qualname__Zis_dml_returningr   __annotations__classmethodr   r   r   r   r   r   r   rD   rD   rD   rF   r     s    

7



!Cr   c                
   @  s   e Zd ZG dd deZedddddddddddddd	d
Zedd Zedd Zedd Z	edd Z
edd Zedd Zedd Zedd Zedd Zedd Zedd  Zd!S )"BulkUDCompileStatec                   @  s~   e Zd ZU dZded< dZded< dZded< dZded	< dZded
< dZ	ded< dZ
ded< eZdZdZdZdZded< dS )z)BulkUDCompileState.default_update_optionsautor*   _dml_strategyr,   _synchronize_sessionFr:   _can_use_returning_is_delete_using_is_update_fromT
_autoflushNOptional[Mapper[Any]]_subject_mapper_populate_existing)r   r   r   r   r   r   r   r   r   r   r   r(   _resolved_values_eval_condition_matched_rows_identity_tokenr   rD   rD   rD   rF   default_update_options{  s   
r   Fis_multitableis_update_fromis_delete_usingis_executemanyr   r|   r:   dialectr<   r   r   r   r   rB   c                C  s
   t  d S rC   )rk   )r   r   r<   r   r   r   r   rD   rD   rF   can_use_returning  s    z$BulkUDCompileState.can_use_returningc           
      C  s  t jdh d||j\}}||d< z|jd }W n tyP   dsLJ dY n0 |rn|j|d< |d|ji7 }d	|jjvr|d
di7 }nNt	|t
s|jdkr|d
di7 }q|jdkrtdn|jdkr|d
di7 }|j}	|	d ur|	dvrtd|jdkr|	dkrtd|s|jr.|  |jdkr|jdkr\| ||||||}nB|jdkr~| ||||||}n |jdkr| ||||||}n$|jdkr|jdkr|ddi7 }||j|j|j|j|jd}|t|d|ifS )N_sa_orm_update_options>   dml_strategyr   r   populate_existingsynchronize_session	autoflushidentity_tokenclauser   F0statement had 'orm' plugin but no plugin_subjectr<   r   r   r   	core_onlyr   ormrc   HCan't use "bulk" ORM insert strategy without passing separate parameters)r   evaluatefetchFzSValid strategies for session synchronization are 'auto', 'evaluate', 'fetch', Falser   zkThe 'fetch' synchronization strategy is not available for 'bulk' ORM updates (i.e. multiple parameter sets)r   r   )r   r   r   r   r   )r   r   from_execution_optionsr   r   KeyErrorr<   rS   r   r   rm   r   sa_excInvalidRequestErrorr   ArgumentErrorr   _do_pre_synchronize_auto_do_pre_synchronize_evaluate_do_pre_synchronize_fetch	_annotater   r   r   r   immutabledictr   )
r   ri   r   r\   r9   r   is_pre_eventupdate_optionsr   syncrD   rD   rF   orm_pre_session_exec  s    	






z'BulkUDCompileState.orm_pre_session_execc                 C  s   |d }|j dkrJ|jdkr.| |||| qr|jdkrr| |||| n(|j dkrr|jdkrn| |||| |S | ||||||S )Nr   r   r   r   rc   )r   r   _do_post_synchronize_evaluate_do_post_synchronize_fetch"_do_post_synchronize_bulk_evaluater   )r   ri   r   r\   r9   r   r   r  rD   rD   rF   orm_setup_cursor_result  s0    




z*BulkUDCompileState.orm_setup_cursor_resultc                   s~   d}j rjnd djf|v rF|tfdd|djf D 7 }jjdur`|jjf7 } rzt fdd|D }|S )a  Apply extra criteria filtering.

        For all distinct single-table-inheritance mappers represented in the
        table being updated or deleted, produce additional WHERE criteria such
        that only the appropriate subtypes are selected from the total results.

        Additionally, add WHERE criteria originating from LoaderCriteriaOptions
        collected from the statement.

        rD   NZadditional_entity_criteriac                 3  s(   | ] }|j s|j u r| V  qd S rC   )Zinclude_aliasesr   Z_resolve_where_criteria)rK   Zae)r   rD   rF   r`   P  s   z@BulkUDCompileState._adjust_for_extra_criteria.<locals>.<genexpr>c                 3  s   | ]}  |V  qd S rC   )traverse)rK   crit)adapterrD   rF   r`   \  rN   )r   Z_adapterr<   ru   Z_single_table_criterion)r   global_attributesr   Zreturn_critrD   )r  r   rF   _adjust_for_extra_criteria;  s"    
z-BulkUDCompileState._adjust_for_extra_criteriac                   sX   z.|j |jj ur ||j j n||j W n tyD   g  Y S 0  fdd|D S )a  return rows that indicate PK cols in mapper.primary_key position
        for RETURNING rows.

        Prior to 2.0.36, this method seemed to be written for some kind of
        inheritance scenario but the scenario was unused for actual joined
        inheritance, and the function instead seemed to perform some kind of
        partial translation that would remove non-PK cols if the PK cols
        happened to be first in the row, but not otherwise.  The joined
        inheritance walk feature here seems to have never been used as it was
        always skipped by the "local_table" check.

        As of 2.0.36 the function strips away non-PK cols and provides the
        PK cols for the table in mapper PK order.

        c                   s   g | ]} |qS rD   rD   rK   rowpk_keysrD   rF   rM     rN   z@BulkUDCompileState._interpret_returning_rows.<locals>.<listcomp>)r   rh   Z_tuple_getterr   r   )r   r   r<   rowsrD   r  rF   _interpret_returning_rows`  s    
z,BulkUDCompileState._interpret_returning_rowsc           
        s   |j |j}fdd|D }|j  d ur> fdd|D }g }|D ]<\}}}||}	|	du sj|	tju rF|||||	tju f qF|S )Nc                   s.   g | ]&}|j  r|js| ||jfqS rD   )r<   r   ZexpiredobjrI   rJ   rU   rD   rF   rM     s   zGBulkUDCompileState._get_matched_objects_on_criteria.<locals>.<listcomp>c                   s&   g | ]\}}}|j  kr|||fqS rD   r   )rK   r  rL   rO   r  rD   rF   rM     s   
T)r   r   r   r   Z_EXPIRED_OBJECTappend)
r   r  rv   eval_conditionraw_datar   r  rL   rO   Zevaled_conditionrD   )r   r<   rF    _get_matched_objects_on_criteria  s2    

z3BulkUDCompileState._get_matched_objects_on_criteriac                 C  s~   |j }|j}t|}d}|jr*||j7 }i }|jD ]}|jr4|| q4|r^|| ||7 }|rn|j	| }	ndd }
|
}	|	S )NrD   c                 S  s   dS )NTrD   )r  rD   rD   rF   r     s    zJBulkUDCompileState._eval_condition_from_statement.<locals>._eval_condition)
r   r   r   _EvaluatorCompiler_where_criteriar   Z_is_criteria_optionZget_global_criteriar  process)r   r  r   r<   
target_clsevaluator_compilerr  r  optr  r   rD   rD   rF   _eval_condition_from_statement  s"    


z1BulkUDCompileState._eval_condition_from_statementc                 C  sT   z|  ||}W n tjy$   Y n0 ||dd S |ddi7 }| ||||||S )a  setup auto sync strategy


        "auto" checks if we can use "evaluate" first, then falls back
        to "fetch"

        evaluate is vastly more efficient for the common case
        where session is empty, only has a few objects, and the UPDATE
        statement can potentially match thousands/millions of rows.

        OTOH more complex criteria that fails to work with "evaluate"
        we would hope usually correlates with fewer net rows.

        r   )r   r   r   r   )r!  r   UnevaluatableErrorr   )r   ri   r   r\   r9   r   r  r  rD   rD   rF   r     s&    z+BulkUDCompileState._do_pre_synchronize_autoc           	   
   C  sT   z|  ||}W n6 tjyF } ztd| |W Y d }~n
d }~0 0 |d|i S )Nz{Could not evaluate current criteria in Python: "%s". Specify 'fetch' or False for the synchronize_session execution option.r   )r!  r   r"  r   r   )	r   ri   r   r\   r9   r   r  r  errrD   rD   rF   r     s    
z/BulkUDCompileState._do_pre_synchronize_evaluatec                 C  s6   |j r
g S |jrt|jS |jr.t|j S g S d S rC   )Z_multi_values_ordered_valuesrm   _valuesrp   )r   r<   r   rD   rD   rF   _get_resolved_values  s    
z'BulkUDCompileState._get_resolved_valuesc              	   C  sj   g }|D ]\\}}|rVt |tjrVz|j| }W n tjyB   Y qd0 ||j|f qt	d| q|S )NzCAttribute name not found, can't be synchronized back to objects: %r)
r   r   ZColumnElement_columntopropertyorm_excZUnmappedColumnErrorr  rX   r   r   )r   r<   resolved_valuesvaluesr   r   r   rD   rD   rF   _resolved_keys_as_propnames  s    z.BulkUDCompileState._resolved_keys_as_propnamesc                   sv   j tjjf  j|j }|j|_d  ddd fdd}|j|||||d}	|		 }
|
 d S )Nr/   r   )orm_contextrB   c                   sz   | j jf i | j}j|jjj| jd} d urL |krft	dn| jrb|sbt	dn| |rrt
 S d S d S )N)r   r   r   zjFor synchronize_session='fetch', can't mix multiple backends where some support RETURNING and others don'tzFor synchronize_session='fetch', can't use multiple parameter sets in ORM mode, which this backend does not support with RETURNING)ri   Zget_bindr   r   r   r   r   r   r   r   r   r   )r,  bindZper_bind_resultr   r   r<   r  rD   rF   skip_for_returningP  s*    
zHBulkUDCompileState._do_pre_synchronize_fetch.<locals>.skip_for_returning)r9   r   Z
_add_event)r   r   )
r   r    r   Zselect_identity_tokenselect_fromr   r   r  executeZfetchall)r   ri   r   r\   r9   r   r  Zselect_stmtr/  r   matched_rowsrD   r.  rF   r   .  s,    
!z,BulkUDCompileState._do_pre_synchronize_fetchN)r   r   r   r$   r   r   r   r  r	  r  r  r  r!  r   r   r&  r+  r   rD   rD   rD   rF   r   z  s:    
x
+
$
"
&

/



r   r   insertc                	      s   e Zd ZU G dd deZdZded< edd Zedd	d
dddddddZ	ed d fddZ
edd Zdd Zdd Z  ZS )BulkORMInsertc                   @  sV   e Zd ZU dZded< dZded< dZded< dZd	ed
< dZded< dZ	ded< dS )z$BulkORMInsert.default_insert_optionsr   r*   r   Fr:   _render_nulls_return_defaultsNr   r   Tr   r   )
r   r   r   r   r   r5  r6  r   r   r   rD   rD   rD   rF   default_insert_options  s   
r7  NzOptional[FromStatement]r   c           	      C  s  t jdh d||j\}}||d< z|jd }W n tyP   dsLJ dY n0 |rn|j|d< |d|ji7 }|s|jd	kr|d
di7 }q|jdkrt	dn|jd	kr|d
di7 }|jdkr|st
j}n|t
j}|s|jr|  |d|ji}|t|d|ifS )N_sa_orm_insert_options>   rA   r   r   r   r   r   Fr   r<   r   r   r   r   rc   r   rawr   )r4  r7  r   r   r   r   r<   r   r   r   r   Z_orm_load_exec_optionsr   r   r   r   r  )	r   ri   r   r\   r9   r   r  insert_optionsr   rD   rD   rF   r    sT    






z"BulkORMInsert.orm_pre_session_execr0   z
dml.Insertr5   r+   r.   r3   _result.Resultri   r   r\   r9   r   r]   rB   c              
   C  s<  | d| j}|jdvr"td|jdkrD|j||p8i |d}|S |jdkr|j}	|jd urt|	jrtt	d|	 |	d usJ |j
d usJ t|	tdt|tr|gn||j
d	|j|j||d
}n&|jdkr|j||pi |d}nt t|js|S |jr(| dtj}
|
ddi7 }
|d|
i}| ||||||S )Nr8  )r9  rc   r   r   zHValid strategies for ORM insert strategy are 'raw', 'orm', 'bulk', 'autor9  )r9   rc   z`bulk INSERT with a 'post values' clause (typically upsert) not supported for multi-table mapper Iterable[Dict[str, Any]]F)r?   r@   rA   r8   r9   r   r   r   T)r   r7  r   r   r   r1  r   Z_post_values_clauseZ_multiple_persistence_tablesr   _transactionrG   r   r   rI   r6  r5  AssertionErrorr:   rs   r   r   r   r   r   )r   ri   r   r\   r9   r   r]   r:  r   r<   r   rD   rD   rF   orm_execute_statement  sz    







z#BulkORMInsert.orm_execute_statement)rB   c                   s~   t tt j||fi |}|d ur.|j }nd}|s:|S |jd }|jdd}|dkrf|| n|dkrz|	|| |S )NTr   r   r9  rc   r   )
r   r4  superr   stackr   r   r   _setup_for_bulk_insert_setup_for_orm_insert)r   r   r   kwr   toplevelr<   r   	__class__rD   rF   r   )  s     

z"BulkORMInsert.create_for_statementc                   s    dd  fdd|  D D S )Nc                 S  s&   i | ]\}}}|d ur|j n||qS rC   rW   )rK   colr   r   rD   rD   rF   r   B  s   z<BulkORMInsert._resolved_keys_as_col_keys.<locals>.<dictcomp>c                 3  s$   | ]\}} j |||fV  qd S rC   )r   r   r   rU   rD   rF   r`   D  s   z;BulkORMInsert._resolved_keys_as_col_keys.<locals>.<genexpr>)rp   )r   r<   Zresolved_value_dictrD   rU   rF   _resolved_keys_as_col_keys@  s
    
z(BulkORMInsert._resolved_keys_as_col_keysc                 C  s0   t tj| j }}| j||||dd}|| _d S )NFr   r   )r   r   Insertr   r   )r   r   r<   r   r   rD   rD   rF   rD  I  s    z#BulkORMInsert._setup_for_orm_insertc                   s   t tj| j }}|j}|d |d   }| } |_| jrX fdd| j D | _| j	||||dd}| j
dur| j
jjrtd|| _dS )	zestablish an INSERT statement within the context of
        bulk insert.

        This method will be within the "conn.execute()" call that is invoked
        by persistence._emit_insert_statement().

        Z_emit_insert_tableZ_emit_insert_mapperc                   s    i | ]\}}|j  u r||qS rD   rS   rK   rI  valZemit_insert_tablerD   rF   r   i  s   
z8BulkORMInsert._setup_for_bulk_insert.<locals>.<dictcomp>TrK  NzCan't use RETURNING * with bulk ORM INSERT.  Please use a different INSERT form, such as INSERT..VALUES or INSERT with a Core Connection)r   r   rL  r   r   _clonerS   _dict_parametersrp   r   r   r   r   r   CompileError)r   r   r   r   anZemit_insert_mapperrD   rP  rF   rC  U  s4    
	z$BulkORMInsert._setup_for_bulk_insert)r   r   r   r$   r7  r   r   r   r  r@  r   rJ  rD  rC  __classcell__rD   rD   rG  rF   r4    s   

CX
r4  updatec                
      s   e Zd Zedd Zdd Zdd Zeddd	d
dddd fddZedddddddddddddddZedd Z	edd Z
edd Zedd  Z  ZS )!BulkORMUpdatec                 K  s   |  | }|jdd}|j }|r:|dkr:||| nL|dksV|dkrnd|jjvrntj|||fi | n|rz|dv r||| |S )Nr   unspecifiedrc   r   r   )r   rX  )	__new__r   r   rB  _setup_for_bulk_updaterS   r'   __init___setup_for_orm_update)r   r   r   rE  r   r   rF  rD   rD   rF   r     s"    

z"BulkORMUpdate.create_for_statementc                 K  s^  |}|j  }|jjd }|j | _}| ||| _| j||||d |jrVt| j| _|	 }|jjd |u rv|j
|_|jr| j|_n|jr| j|_| | j|}	|	r|j|	 }tj| ||fi | d}
|sd }n|jdd }|jdd }|dur|dko| j|j|| jd}|dkr:|r:d}
|j|jj }|rT| j|||||
d	}|| _d S )
Nr   rF  Zprocess_criteria_for_toplevelFr   r   r   )r   TrK  )rB  rS   r   r<   r&  r   _init_global_attributesr%  rI   rQ  r   r$  r  r  wherer'   r[  r   r   r   r   r@   r   r   r   )r   r   r   rE  r   rF  r   r<   new_stmtnew_critr   r   r   rD   rD   rF   r\    sj    




z#BulkORMUpdate._setup_for_orm_updatec                   s   t tj|}|j}|d |d   }| } |_tj| ||fi | | jrXt	
d| jrx fdd| j D | _|| _dS )zestablish an UPDATE statement within the context of
        bulk insert.

        This method will be within the "conn.execute()" call that is invoked
        by persistence._emit_update_statement().

        Z_emit_update_tableZ_emit_update_mapperzbulk ORM UPDATE does not support ordered_values() for custom UPDATE statements with bulk parameter sets.  Use a non-bulk UPDATE statement or use values().c                   s    i | ]\}}|j  u r||qS rD   rM  rN  Zemit_update_tablerD   rF   r     s   
z8BulkORMUpdate._setup_for_bulk_update.<locals>.<dictcomp>N)r   r   ZUpdater   rQ  rS   r'   r[  r$  r   r   rR  rp   r   )r   r   r   rE  rT  _rD   rb  rF   rZ    s"    
z$BulkORMUpdate._setup_for_bulk_updater0   z
dml.Updater5   r+   r.   r3   r;  r<  c              	     s  | d| j}|jr<| dtj}|ddi7 }|d|i}|jdvrPtd|jdkr|j	 }	|j
dkspJ |j	r|j
d	krtd
|j}
|
d usJ |jd usJ t|
tdt|tr|gn||jdd||	d}| ||||||S t ||||||S d S )Nr   r   r   T)r   r   rc   r   zOValid strategies for ORM UPDATE strategy are 'orm', 'auto', 'bulk', 'core_only'rc   r   r   zbulk synchronize of persistent objects not supported when using bulk update with additional WHERE criteria right now.  add synchronize_session=None execution option to bypass synchronize of persistent objects.r=  F)r?   r}   rz   r{   )r   r   r   r   r   r   r   r   r   r  r   r   r   r>  r   r   r   rI   r	  rA  r@  )r   ri   r   r\   r9   r   r]   r  r   r{   r<   r   rG  rD   rF   r@  #  sp    

	z#BulkORMUpdate.orm_execute_statementFr   r   r|   r:   r   c                C  sL   |j o|jj}|sdS |r |jS |r*|jS |rH|jsHtd|j ddS )NF	Dialect "z" does not support RETURNING with UPDATE..FROM; for synchronize_session='fetch', please add the additional execution option 'is_update_from=True' to the statement to indicate that a separate SELECT should be used for this backend.T)Zupdate_returningr   implicit_returningZupdate_executemany_returningZupdate_returning_multifromr   rS  r   r   r   r<   r   r   r   r   Znormal_answerrD   rD   rF   r   y  s    
zBulkORMUpdate.can_use_returningc                   s   |sd S |j }dd |jD }|j}|D ] | fdd|D |j}||}	|	sXq(t |}
|	j}|	j	
|
}|D ]}||v r| | ||< q||	jj|	d | |	|t| |

||}|r(|	|| q(d S )Nc                 S  s   g | ]
}|j qS rD   rW   )rK   proprD   rD   rF   rM     rN   zDBulkORMUpdate._do_post_synchronize_bulk_evaluate.<locals>.<listcomp>c                 3  s   | ]} | V  qd S rC   rD   rg   paramrD   rF   r`     rN   zCBulkORMUpdate._do_post_synchronize_bulk_evaluate.<locals>.<genexpr>)r   rt   identity_mapidentity_key_from_primary_keyr   Zfast_get_stater   
differencerI   
unmodifiedr   managerdispatchrefresh_commitrm   _expire_attributes)r   ri   r\   r   r  r<   r  rj  identity_keyrL   evaluated_keysrO   to_evaluaterX   	to_expirerD   rh  rF   r    s4    

z0BulkORMUpdate._do_post_synchronize_bulk_evaluatec              
   C  sF   |  ||j }| ||||jjd dd |D | |  d S )Nr   c                 S  s   g | ]\}}}}|||fqS rD   rD   )rK   r  rL   rO   rc  rD   rD   rF   rM     rN   z?BulkORMUpdate._do_post_synchronize_evaluate.<locals>.<listcomp>)r  rj  
all_states#_apply_update_set_values_to_objectsr   compiled_parametersprefetch_colspostfetch_cols)r   ri   r   r   r  matched_objectsrD   rD   rF   r    s    
z+BulkORMUpdate._do_post_synchronize_evaluatec           	   
     s   j |j}|r2| ||}fdd|D }nj} fddfdddd |D D D }|sld S |  ||jjd dd |D | |  d S )Nc                   s   g | ]}t | jf qS rD   ru   r   r  r  rD   rF   rM     s   z<BulkORMUpdate._do_post_synchronize_fetch.<locals>.<listcomp>c                   s    g | ]}| j v r j | qS rD   )rj  )rK   rs  )ri   rD   rF   rM     s   
c                   s6   g | ].\}}j d u s |j kr jt||dqS )Nr  )r   rk  rm   )rK   r   r   )target_mapperr  rD   rF   rM     s   

c                 S  s    g | ]}|d d |d fqS )r   rD   r  rD   rD   rF   rM     s   r   c                 S  s"   g | ]}|t |t |fqS rD   )r   instance_stateinstance_dict)rK   r  rD   rD   rF   rM     s
   )	r   returned_defaults_rowsr  r   rx  r   ry  rz  r{  )	r   ri   r   r   r  r  pk_rowsr2  ZobjsrD   )ri   r  r  rF   r    s<    


z(BulkORMUpdate._do_post_synchronize_fetchc              	     s  |j j}t|}	| |}
| |
}i }|D ]>\}}z|	tt	j
|}W n tjyj   Y q60 |||< q6t| dd |D }t } fdd|D }fdd|D }fdd|D }|D ]\}}}| fdd|D  ||j| |j}|D ] }||v r|| |||< q|jj|d	| ||t| |||}|r||| || q|| d	S )
zeapply values to objects derived from an update statement, e.g.
        UPDATE..SET <values>

        c                 S  s   h | ]\}}|qS rD   rD   r   rD   rD   rF   	<setcomp>5  rN   zDBulkORMUpdate._apply_update_set_values_to_objects.<locals>.<setcomp>c                   s.   h | ]&}|j  v r|jv r|j vr|qS rD   )rX   r'  r   effective_paramsrt  r<   rD   rF   r  9  s
   


c                   s"   h | ]}| j v r j | jqS rD   r'  rX   r   rU   rD   rF   r  @  s   
c                   s   g | ]} j | j|jfqS rD   r  r   rU   rD   rF   rM   F  s   zEBulkORMUpdate._apply_update_set_values_to_objects.<locals>.<listcomp>c                   s   i | ]\}}| | qS rD   rD   )rK   Zcol_to_propZc_key)r  rD   rF   r   M  s   zEBulkORMUpdate._apply_update_set_values_to_objects.<locals>.<dictcomp>N)r   r   r   r  r&  r+  r  r   r   r   r   r"  rm   r   r   rl  rV  rr  rI   rm  r   rn  ro  rp  rq  addZ_register_altered)r   ri   r  r   r  r|  rz  r{  r  r  r)  Zresolved_keys_as_propnamesZvalue_evaluatorsrX   valueZ
_evaluatorZattribrv   Zto_prefetchrv  Zprefetch_transferr  rL   rO   ru  rD   r  rF   rx    s`    





z1BulkORMUpdate._apply_update_set_values_to_objects)r   r   r   r   r   r\  rZ  r@  r   r  r  r  rx  rU  rD   rD   rG  rF   rW    s(   
b$ U $
*

5rW  deletec                
      s   e Zd Zedd Zeddddddd	d
 fddZedddddddddddddddZedd Zedd Z  Z	S )BulkORMDeletec                 K  sp  |  | }|jdd}|dks4|dkrNd|jjvrNtj|||fi | |S |j }|}|jjd }|j |_}	|j||||d |	 }
|
jjd |	u r|	j
|
_| |j|	}|r|
j| }
tj||
|fi | d}|sd }n|jdd }|jdd }|dur4|d	ko2|j|j|	|j|jd
dd}|rLd}|
j|
jj }
|rf|j|||
|	|d}
|
|_|S )Nr   rX  r   r   r]  Fr   r   r   r   )r   r   TrK  )rY  r   r   rS   r%   r[  rB  r<   r^  rQ  r   r  r  r_  r   r   r   r@   r   r   r   )r   r   r   rE  r   r   rF  r   r   r<   r`  ra  r   r   r   rD   rD   rF   r   m  s    




z"BulkORMDelete.create_for_statementr0   z
dml.Deleter5   r+   r.   r3   r;  r<  c                   sL   | d| j}|jdkr"td|jdvr6tdt ||||||S )Nr   rc   zBulk ORM DELETE not supported right now. Statement may be invoked at the Core level using session.connection().execute(stmt, parameters))r   r   r   zGValid strategies for ORM DELETE strategy are 'orm', 'auto', 'core_only')r   r   r   r   r   r   rA  r@  )r   ri   r   r\   r9   r   r]   r  rG  rD   rF   r@    s    


z#BulkORMDelete.orm_execute_statementFr   r   r|   r:   r   c                C  sB   |j o|jj}|sdS |r |jS |r>|js>td|j ddS )NFrd  z" does not support RETURNING with DELETE..USING; for synchronize_session='fetch', please add the additional execution option 'is_delete_using=True' to the statement to indicate that a separate SELECT should be used for this backend.T)Zdelete_returningr   re  Zdelete_returning_multifromr   rS  r   rf  rD   rD   rF   r     s    
zBulkORMDelete.can_use_returningc                 C  sZ   |  ||j }g }|D ],\}}}	}
|
r<||	|jj q|| q|rV|| d S rC   )r  rj  rw  Z_expireZ	_modifiedr  _remove_newly_deleted)r   ri   r   r   r  r|  Z	to_deleterc  rL   rO   Zis_partially_expiredrD   rD   rF   r    s    z+BulkORMDelete._do_post_synchronize_evaluatec                   s    j }|j}|r2| |||} fdd|D }n j}|D ]L}	|	dd }
|	d }|jt|
|d}||jv r<|t	|j| g q<d S )Nc                   s   g | ]}t | jf qS rD   r}  r  r~  rD   rF   rM   3  s   z<BulkORMDelete._do_post_synchronize_fetch.<locals>.<listcomp>r   r  r  )
r   r  r  r   rk  rm   rj  r  r   r  )r   ri   r   r   r  r  r  r  r2  r  r   r   rs  rD   r~  rF   r  &  s0    

z(BulkORMDelete._do_post_synchronize_fetch)
r   r   r   r   r   r@  r   r  r  rU  rD   rD   rG  rF   r  k  s   
[  (
r  )O__doc__
__future__r   typingr   r   r   r   r   r   r	   r
   r    r   r   r   r   r(  r   r   baser   r   r   r   r   r   r   Zenginer   r   r   sqlr   r   r   r   r    r!   Zsql.baser"   r#   r$   Zsql.dmlr%   r&   r'   r(   Zutil.typingr)   Z_typingr*   r+   r,   r<   r-   ri   r.   r/   r0   r1   rL   r2   r3   r4   Zengine.interfacesr5   objectr6   rG   r   rn   r   r   Z
plugin_forr4  rW  r  rD   rD   rD   rF   <module>
   s   	$	$" "" \ x    

  
   i
