o
    h                    @  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
r7d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dodJdKZFe	d8d8d9dpdNdKZFdOdOd9dqdQdKZFe	d8dRdSdrdXdYZGe	d8dRdSdsd\dYZGdOdRdSdtd^dYZGd_d` ZHG dadb dbeZIG dcdd ddeIZJe*KdedfG dgdh dheIe.ZLe*KdediG djdk dkeJe/ZMe*KdedlG dmdn dneJe-ZNdOS )uzoadditional 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_optionsmapper
Mapper[_O]mappings<Union[Iterable[InstanceState[_O]], Iterable[Dict[str, Any]]]session_transactionr1   isstatesboolreturn_defaultsrender_nullsr8   Literal[None]r9   $Optional[OrmExecuteOptionsParameter]returnNonec                C     d S N r:   r<   r>   r?   rA   rB   r8   r9   rI   rI   s/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/sqlalchemy/orm/bulk_persistence.py_bulk_insertJ      rL   Optional[dml.Insert]cursor.CursorResult[Any]c                C  rG   rH   rI   rJ   rI   rI   rK   rL   X   rM   N"Optional[cursor.CursorResult[Any]]c                  s  j }|jjrtd|r1trtttt  |r)dd D }	dd |	D n(dd D n tr>ttt	t
tf  |rEtndd D t || d }
fdd|j D }|rid}nt|d	krrd}nd
}|D ]W\}}|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|}
qv|jr|sJ |
|}
qv|r|rj}dd jD }|	D ]\}|tfdd|D d f|_q|d ur|
d usJ |
S d S )NzJconnection_callable / per-instance sharding not supported in bulk_insert()c                 S  s   g | ]}||j fqS rI   dict.0staterI   rI   rK   
<listcomp>       z _bulk_insert.<locals>.<listcomp>c                 S  s   g | ]\}}|qS rI   rI   )rT   rU   dict_rI   rI   rK   rV          c                 S     g | ]}|j qS rI   rQ   rS   rI   rI   rK   rV          c                 S     g | ]}t |qS rI   rQ   rT   mrI   rI   rK   rV      rY   c                   s"   g | ]\}}| j v r||fqS rI   )_pks_by_table)rT   tablempr:   rI   rK   rV      s
    
Tr   Fc                       g | ]}|j  d  v r|j qS r   keyrT   br<   rI   rK   rV      
    rI   c           	   	   3  s4    | ]\}}}}}}}}d || |||fV  qd S rH   rI   )	rT   rU   
state_dictparamsra   connvalue_paramshas_all_pkshas_all_defaults
connectionr:   rI   rK   	<genexpr>   s*    
z_bulk_insert.<locals>.<genexpr>c                 3  s    | ]	}d | fV  qd S rH   rI   rT   mappingrq   rI   rK   rs      s    )bulkrA   rB   include_bulk_keys)bookkeepingr8   r9   c                 S  rZ   rI   re   )rT   prI   rI   rK   rV      r[   c                   s   g | ]} | qS rI   rI   rT   rf   )rX   rI   rK   rV      rY   )base_mappersessionconnection_callableNotImplementedErrorr	   r   r   r2   r6   r   strr   list_expand_compositesrr   _sorted_tablesitemslen_get_embedded_bindparamsr   _collect_insert_commands_emit_insert_statements
_returningreturns_rowssplice_horizontally_identity_class_identity_key_propstuplerf   )r:   r<   r>   r?   rA   rB   r8   r9   r{   statesreturn_resultmappers_to_runrx   r`   super_mapperextra_bp_namesrecordsr   identity_clsidentity_propsrU   rI   )rr   rX   r:   r<   rK   rL   f   s   







T)use_orm_update_stmtenable_check_rowcountMapper[Any]update_changed_onlyr   r   c                C  rG   rH   rI   r:   r<   r>   r?   r   r   r   rI   rI   rK   _bulk_update      
r   Optional[dml.Update]_result.Result[Any]c                C  rG   rH   rI   r   rI   rI   rK   r     r   Optional[_result.Result[Any]]c                  s.  j }jjrjjhfdd |r.|r& fddD ndd D ndd D t |jjrBtd|	||d urVfdd|
 D nd	}|j D ]/\}	}
|
rk|	jvrlq]tjd |	fd
dD d||d}tj|d |
|	|d||d q]|d urt S d S )Nc                   s    fdd j  D S )Nc                   s(   i | ]\}}|j v s| v r||qS rI   )committed_staterT   kv)search_keysrU   rI   rK   
<dictcomp>)  s
    z7_bulk_update.<locals>._changed_dict.<locals>.<dictcomp>)rR   r   )r:   rU   )r   )rU   rK   _changed_dict(  s   z#_bulk_update.<locals>._changed_dictc                   s   g | ]} |qS rI   rI   rS   )r   r:   rI   rK   rV   1  rW   z _bulk_update.<locals>.<listcomp>c                 S  rZ   rI   rQ   rS   rI   rI   rK   rV   3  r[   c                 S  r\   rI   rQ   r]   rI   rI   rK   rV   5  rY   zJconnection_callable / per-instance sharding not supported in bulk_update()c                   rc   rd   re   rg   ri   rI   rK   rV   C  rj   rI   c                 3  s0    | ]}d | j r|j j nd fV  qd S rH   )_version_id_proprf   rt   rq   rI   rK   rs   S  s    
z_bulk_update.<locals>.<genexpr>T)rv   r   rw   F)rx   r   r   )r{   _primary_key_propkeysr   rf   unionr   r|   r}   r~   rr   r   r   r   isar_   r   _collect_update_commands_emit_update_statements_resultnull_result)r:   r<   r>   r?   r   r   r   r{   r   r`   r   r   rI   )r   rr   r:   r<   r   rK   r     s`   





c                   sV   | j   sd S t  } fdd|D }|D ]}||D ]}|| | qqd S )Nc                   s   i | ]	}| |   qS rI   ))_populate_composite_bulk_save_mappings_fnrz   composite_attrsrI   rK   r   z  s    z&_expand_composites.<locals>.<dictcomp>)
compositessetkeysintersection)r:   r<   composite_keys
populatorsru   rf   rI   r   rK   r   t  s   
r   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 ]r\}}ttj|}t|trGt||t	d}|t	u r:ttj||r5tjtj
|t ddn|fV  q|||||E d H  qd|jv re|j}	t|	d |	d }
|||
||E d H  q||sj|ntjtj
|t ddfV  qd S )N)defaultT)type_is_crudentity_namespace	proxy_key)r'   _get_crud_kv_pairsr   expectr   DMLColumnRole
isinstancer   r"   r   ExpressionElementRoler!   NullType_bulk_update_tuples_annotations)clsr:   	statementkv_iteratorneeds_to_be_cacheablecore_get_crud_kv_pairsr   r   desck_annoattrrI   rI   rK   _get_orm_crud_kv_pairs  sV   

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)rR   r   r:   r   )rT   
value_dictr   r   r   rI   rK   rV     s    z8ORMDMLState._get_multi_crud_kv_pairs.<locals>.<listcomp>)_propagate_attrsr:   r'   _get_multi_crud_kv_pairs)r   r   r   rI   r   rK   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   r   r   )r   r   r   r   r   rI   rI   rK   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entityr`   )	r`   r   r:   is_aliased_classr   class___name__r   local_table)r   r   ext_infor:   _label_namerI   rI   rK   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)crI   rI   rK   _ent_for_col  s   zCORMDMLState.get_returning_column_descriptions.<locals>._ent_for_colc                 S  s0   |d u r| S | j dd }|s| S t|j|| S )Nr   )r   r   getattrr   )r   entr   rI   rI   rK   _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   )rf   r   r   r   )rT   r   r   )r   rI   rK   rV     s    zAORMDMLState.get_returning_column_descriptions.<locals>.<listcomp>c                   s   g | ]}| |fqS rI   rI   rT   r   )r   rI   rK   rV     s    )_all_selected_columns)r   r   rI   )r   r   rK   !get_returning_column_descriptions  s   
	
z-ORMDMLState.get_returning_column_descriptions)use_supplemental_colsc          	      C  s   |j rTt|j |dd}|jdi |j}|j|j }|| _t|| | _	}|
| | }d|_ dd |jD }|sB||j |rO|j|jd|i}|S |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)_adapt_on_namesrI   c                 S  s   g | ]}|d ur|qS rH   rI   r   rI   rI   rK   rV   8  s    z4ORMDMLState._setup_orm_returning.<locals>.<listcomp>supplemental_cols)r   r   r9   _execution_optionsoptions_with_optionsselect_statementr   create_for_statementr   !setup_dml_returning_compile_state	_generateprimary_columnsextendprimary_keyrA   	returning)	selfcompilerorm_level_statementdml_level_statement
dml_mapperr   fsfsccols_to_returnrI   rI   rK   _setup_orm_returning  s8   

z ORMDMLState._setup_orm_returningc              	   C  sV   |j }|jj}|jr)|jjjs)|dtj}	t|j|j	||||	||}
t
||
S |S )N_sa_orm_load_options)r   compiledcompile_stater   compile_options_is_starr   r   default_load_optionsr   r   	instances)r   r|   r   rl   r9   bind_argumentsr   execution_contextr  load_optionsquerycontextrI   rI   rK   _return_orm_returningV  s*   

z!ORMDMLState._return_orm_returning)r   
__module____qualname__is_dml_returningr   __annotations__classmethodr   r   r   r   r   r  r  rI   rI   rI   rK   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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  rI   rI   rI   rK   default_update_options{  s   
 r"  Fis_multitableis_update_fromis_delete_usingis_executemanydialectr   r:   r   r$  r@   r%  r&  r'  rE   c                C  s   t  rH   )r~   )r   r(  r:   r$  r%  r&  r'  rI   rI   rK   can_use_returning  s   z$BulkUDCompileState.can_use_returningc           
      C  s  t jdh d||j\}}||d< z|jd }W n ty$   J dw |r3|j|d< |d|ji7 }d	|jjvr@|d
di7 }n't	|t
s\|jdkrQ|d
di7 }n|jdkr[tdn|jdkrg|d
di7 }|j}	|	d ur|	dvrwtd|jdkr|	dkrtd|s|jr|  |jdkr|jdkr| ||||||}n0|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>   	autoflushdml_strategyidentity_tokenr%  r&  populate_existingsynchronize_sessionclauser   F0statement had 'orm' plugin but no plugin_subjectr:   r  r   r  	core_onlyr  ormrv   HCan't use "bulk" ORM insert strategy without passing separate parameters)r  evaluatefetchFzSValid strategies for session synchronization are 'auto', 'evaluate', 'fetch', Falser6  zkThe 'fetch' synchronization strategy is not available for 'bulk' ORM updates (i.e. multiple parameter sets)r5  r  )r/  r&  r%  r,  r)  )r  r"  from_execution_optionsr   r   KeyErrorr:   r`   r   r   r   r  sa_excInvalidRequestErrorr  ArgumentErrorr  _do_pre_synchronize_auto_do_pre_synchronize_evaluate_do_pre_synchronize_fetch	_annotater  r  r  r   immutabledictr   )
r   r|   r   rl   r9   r	  is_pre_eventupdate_optionsr   syncrI   rI   rK   orm_pre_session_exec  s   	











z'BulkUDCompileState.orm_pre_session_execc                 C  s   |d }|j dkr%|jdkr| |||| n"|jdkr$| |||| n|j dkr9|jdkr7| |||| |S | ||||||S )Nr*  r3  r5  r6  rv   )r  r  _do_post_synchronize_evaluate_do_post_synchronize_fetch"_do_post_synchronize_bulk_evaluater  )r   r|   r   rl   r9   r	  r   rB  rI   rI   rK   orm_setup_cursor_result  s2   




z*BulkUDCompileState.orm_setup_cursor_resultc                   s~   d}j rjnd djf|v r#|tfdd|djf D 7 }jjdur0|jjf7 } r=t 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.

        rI   Nadditional_entity_criteriac                 3  s*    | ]}|j s|j u r| V  qd S rH   )include_aliasesr   _resolve_where_criteria)rT   ae)r   rI   rK   rs   P  s    
z@BulkUDCompileState._adjust_for_extra_criteria.<locals>.<genexpr>c                 3  s    | ]}  |V  qd S rH   )traverse)rT   crit)adapterrI   rK   rs   \  s    )r   _adapterr:   r   _single_table_criterion)r   global_attributesr   return_critrI   )rO  r   rK   _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y"   g  Y S w  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 rI   rI   rT   rowpk_keysrI   rK   rV     rY   z@BulkUDCompileState._interpret_returning_rows.<locals>.<listcomp>)r   r{   _tuple_getterr   r8  )r   r   r:   rowsrI   rW  rK   _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 s5|	tju rA|||||	tju f q#|S )Nc                   s.   g | ]}|j  r|js| ||jfqS rI   )r:   r   expiredobjrR   rS   rb   rI   rK   rV     s    
zGBulkUDCompileState._get_matched_objects_on_criteria.<locals>.<listcomp>c                   s&   g | ]\}}}|j  kr|||fqS rI   r-  )rT   r]  rU   rX   r^  rI   rK   rV     s
    
T)r  r  r!  r   _EXPIRED_OBJECTappend)
r   rB  r   eval_conditionraw_datar   r]  rU   rX   evaled_conditionrI   )r-  r:   rK    _get_matched_objects_on_criteria  s0   


z3BulkUDCompileState._get_matched_objects_on_criteriac                 C  s   |j }|j}t|}d}|jr||j7 }i }|jD ]
}|jr$|| q|r/|| ||7 }|r8|j	| }	|	S dd }
|
}	|	S )NrI   c                 S  s   dS )NTrI   )r]  rI   rI   rK   r    s   zJBulkUDCompileState._eval_condition_from_statement.<locals>._eval_condition)
r  r   r   _EvaluatorCompiler_where_criteriar   _is_criteria_optionget_global_criteriarT  process)r   rB  r   r:   
target_clsevaluator_compilerrN  rR  optra  r  rI   rI   rK   _eval_condition_from_statement  s&   




z1BulkUDCompileState._eval_condition_from_statementc                 C  sT   z|  ||}W n
 tjy   Y nw ||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.

        r5  )r  r  r  r6  )rm  r   UnevaluatableErrorr>  )r   r|   r   rl   r9   r	  rB  ra  rI   rI   rK   r<    s(   z+BulkUDCompileState._do_pre_synchronize_autoc           	   
   C  sH   z|  ||}W n tjy } ztd| |d }~ww |d|i S )Nz{Could not evaluate current criteria in Python: "%s". Specify 'fetch' or False for the synchronize_session execution option.r  )rm  r   rn  r9  r:  )	r   r|   r   rl   r9   r	  rB  ra  errrI   rI   rK   r=    s"   
z/BulkUDCompileState._do_pre_synchronize_evaluatec                 C  s2   |j rg S |jrt|jS |jrt|j S g S rH   )_multi_values_ordered_valuesr   _valuesr   )r   r:   r   rI   rI   rK   _get_resolved_values  s   
z'BulkUDCompileState._get_resolved_valuesc              	   C  sh   g }|D ]-\}}|r+t |tjr+z|j| }W n
 tjy!   Y qw ||j|f qt	d| |S )NzCAttribute name not found, can't be synchronized back to objects: %r)
r   r   ColumnElement_columntopropertyorm_excUnmappedColumnErrorr`  rf   r9  r:  )r   r:   resolved_valuesvaluesr   r   r   rI   rI   rK   _resolved_keys_as_propnames  s   z.BulkUDCompileState._resolved_keys_as_propnamesc                   sp   j tjjf  j|j }|j|_d  d	 fdd}|j|||||d}	|		 }
|
 d S )
Norm_contextr/   rE   r   c                   st   | j jdi | j}j|jjj| jd} d ur& |kr%t	dn| jr0|s0t	d| |r8t
 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 RETURNINGrI   )r|   get_bindr	  r)  r(  r  r  r'  r9  r:  r   r   )r{  bindper_bind_resultr)  r   r:   rB  rI   rK   skip_for_returningP  s,   
zHBulkUDCompileState._do_pre_synchronize_fetch.<locals>.skip_for_returning)r9   r	  
_add_event)r   r  )r{  r/   rE   r   )
r  r    r   select_identity_tokenselect_fromr   r   rf  executefetchall)r   r|   r   rl   r9   r	  rB  select_stmtr  r   matched_rowsrI   r  rK   r>  .  s*   
!z,BulkUDCompileState._do_pre_synchronize_fetchNr(  r   r:   r   r$  r@   r%  r@   r&  r@   r'  r@   rE   r@   )r   r  r  r$   r"  r  r)  rD  rH  rT  r[  rd  rm  r<  r=  rs  rz  r>  rI   rI   rI   rK   r  z  s<    
x
+
$
"
&

/



r  r3  insertc                      sv   e Zd ZU G dd deZdZded< edd Zed ddZ	e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  r  r  r  r  r  rI   rI   rI   rK   default_insert_options  s   
 r  NzOptional[FromStatement]r   c           	      C  s
  t jdh d||j\}}||d< z|jd }W n ty$   J dw |r3|j|d< |d|ji7 }|sL|jd	krA|d
di7 }n|jdkrKt	dn|jd	krW|d
di7 }|jdkrh|sbt
j}n|t
j}|sq|jrq|  |d|ji}|t|d|ifS )N_sa_orm_insert_options>   r+  r,  rB   r.  r0  r   Fr1  r:   r  r  r  r3  rv   r4  rawr,  )r  r  r7  r   r   r8  r:   r  r9  r:  r   _orm_load_exec_optionsr   r  r?  r   r@  )	r   r|   r   rl   r9   r	  rA  insert_optionsr   rI   rI   rK   rD    sX   






z"BulkORMInsert.orm_pre_session_execr|   r0   r   
dml.Insertrl   r5   r9   r+   r	  r.   rm   r3   rE   _result.Resultc              
   C  s:  | d| j}|jdvrtd|jdkr"|j||pi |d}|S |jdkrb|j}	|jd ur:|	jr:t	d|	 |	d us@J |j
d usGJ t|	tdt|trS|gn||j
d	|j|j||d
}n|jdkrr|j||pmi |d}nt t|js||S |jr| dtj}
|
ddi7 }
|d|
i}| ||||||S )Nr  )r  rv   r3  r  zHValid strategies for ORM insert strategy are 'raw', 'orm', 'bulk', 'autor  )r9   rv   z`bulk INSERT with a 'post values' clause (typically upsert) not supported for multi-table mapper Iterable[Dict[str, Any]]F)r?   rA   rB   r8   r9   r3  r  r  T)r   r  r  r9  r;  r  r  _post_values_clause_multiple_persistence_tablesr:  _transactionrL   r   r   rR   r  r  AssertionErrorr@   r   r  r   r  r   r  )r   r|   r   rl   r9   r	  rm   r  r   r:   r  rI   rI   rK   orm_execute_statement  sx   








z#BulkORMInsert.orm_execute_statementc                   s   t tt j||fi |}|d ur|j }nd}|s|S |jd }|jdd}|dkr4|| |S |dkr>|	|| |S )NTr   r,  r  rv   r3  )
r   r  superr   stackr   r   r   _setup_for_bulk_insert_setup_for_orm_insert)r   r   r   kwr   toplevelr:   r,  	__class__rI   rK   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 rH   re   )rT   colr   r   rI   rI   rK   r   B  s    z<BulkORMInsert._resolved_keys_as_col_keys.<locals>.<dictcomp>c                 3  s&    | ]\}} j |||fV  qd S rH   )r   r   r   rb   rI   rK   rs   D  s    
z;BulkORMInsert._resolved_keys_as_col_keys.<locals>.<genexpr>)r   )r   r:   resolved_value_dictrI   rb   rK   _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   rI   rI   rK   r  I  s   
z#BulkORMInsert._setup_for_orm_insertc                   s   t tj| j }}|j}|d |d  }| } |_| jr, fdd| j D | _| j	||||dd}| j
durE| j
jjrEt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().

        _emit_insert_table_emit_insert_mapperc                       i | ]\}}|j  u r||qS rI   r`   rT   r  valemit_insert_tablerI   rK   r   i  
    
z8BulkORMInsert._setup_for_bulk_insert.<locals>.<dictcomp>Tr  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   r  r   r   _cloner`   _dict_parametersr   r  r   r  r  r9  CompileError)r   r   r   r   anemit_insert_mapperrI   r  rK   r  U  s2   

	
z$BulkORMInsert._setup_for_bulk_insert)r|   r0   r   r  rl   r5   r9   r+   r	  r.   rm   r3   rE   r  )rE   r  )r   r  r  r$   r  r   r  r  rD  r  r   r  r  r  __classcell__rI   rI   r  rK   r    s   
 
CX
r  updatec                      s   e Zd Zedd Zdd Zdd Zed, fddZe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||| |S |dks,|dkr9d|jjvr9tj|||fi | |S |r?|dv rE||| |S )Nr,  unspecifiedrv   r2  r   )r3  r  )	__new__r   r   r  _setup_for_bulk_updater`   r'   __init___setup_for_orm_update)r   r   r   r  r   r,  r  rI   rI   rK   r     s    

z"BulkORMUpdate.create_for_statementc                 K  sT  |}|j  }|jjd }|j | _}| ||| _| j||||d |jr+t| j| _|	 }|jjd |u r;|j
|_|jrC| j|_n|jrJ| j|_| | j|}	|	rX|j|	 }tj| ||fi | d}
|sjd }n|jdd }|jdd }|dur|dko| j|j|| jd}|dkr|rd}
|j|jj }|r| j|||||
d	}|| _d S )
Nr   r  process_criteria_for_toplevelFr/  r)  r6  )r$  Tr  )r  r`   r   r:   rs  r  _init_global_attributesrr  rR   r  r   rq  rT  rR  wherer'   r  r   r)  r(  r$  rA   r   r  r   )r   r   r   r  r   r  r   r:   new_stmtnew_critr   r/  r)  rI   rI   rK   r    sj   



z#BulkORMUpdate._setup_for_orm_updatec                   s   t tj|}|j}|d |d  }| } |_tj| ||fi | | jr,t	
d| jr< 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().

        _emit_update_table_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                   r  rI   r  r  emit_update_tablerI   rK   r     r  z8BulkORMUpdate._setup_for_bulk_update.<locals>.<dictcomp>N)r   r   Updater   r  r`   r'   r  rq  r9  r:  r  r   r   )r   r   r   r  r  _rI   r  rK   r    s"   

z$BulkORMUpdate._setup_for_bulk_updater|   r0   r   
dml.Updaterl   r5   r9   r+   r	  r.   rm   r3   rE   r  c              	     s  | d| j}|jr| dtj}|ddi7 }|d|i}|jdvr(td|jdkrv|j	 }	|j
dks8J |j	rE|j
d	krEtd
|j}
|
d usNJ |jd usUJ t|
tdt|tra|gn||jdd||	d}| ||||||S t ||||||S )Nr*  r  r  T)r3  r  rv   r2  zOValid strategies for ORM UPDATE strategy are 'orm', 'auto', 'bulk', 'core_only'rv   r6  r5  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   r   r   )r   r"  r  r   r  r   r  r9  r;  rf  r  r:  r  r  r   r   r   rR   rH  r  r  )r   r|   r   rl   r9   r	  rm   rB  r  r   r:   r   r  rI   rK   r  #  sn   


	z#BulkORMUpdate.orm_execute_statementFr#  r(  r   r:   r   r$  r@   r%  r&  r'  c                C  sL   |j o|jj}|sdS |r|jS |r|jS |r$|js$t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)update_returningr   implicit_returningupdate_executemany_returningupdate_returning_multifromr9  r  r   r   r(  r:   r$  r%  r&  r'  normal_answerrI   rI   rK   r)  y  s   
zBulkORMUpdate.can_use_returningc                   s   |sd S |j }dd |jD }|j}|D ]X | fdd|D |j}||}	|	s,qt |}
|	j}|	j	
|
}|D ]}||v rJ | ||< q>|	jj|	d | |	|t| |

||}|rl|	|| qd S )Nc                 S  rZ   rI   re   )rT   proprI   rI   rK   rV     r[   zDBulkORMUpdate._do_post_synchronize_bulk_evaluate.<locals>.<listcomp>c                 3  s    | ]} | V  qd S rH   rI   rz   paramrI   rK   rs     s    zCBulkORMUpdate._do_post_synchronize_bulk_evaluate.<locals>.<genexpr>)r  r   identity_mapidentity_key_from_primary_keyr!  fast_get_stater   
differencerR   
unmodifiedr   managerdispatchrefresh_commitr   _expire_attributes)r   r|   rl   r   rB  r:   rX  r  identity_keyrU   evaluated_keysrX   to_evaluaterf   	to_expirerI   r  rK   rG    s:   

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 rI   rI   )rT   r]  rU   rX   r  rI   rI   rK   rV     s    z?BulkORMUpdate._do_post_synchronize_evaluate.<locals>.<listcomp>)rd  r  
all_states#_apply_update_set_values_to_objectsr   compiled_parametersprefetch_colspostfetch_cols)r   r|   r   r   rB  matched_objectsrI   rI   rK   rE    s   
z+BulkORMUpdate._do_post_synchronize_evaluatec           	   
     s   j |j}|r| ||}fdd|D }nj} fddfdddd |D D D }|s6d S |  ||jjd dd |D | |  d S )Nc                      g | ]
}t | jf qS rI   r   r!  rU  rB  rI   rK   rV         z<BulkORMUpdate._do_post_synchronize_fetch.<locals>.<listcomp>c                   s    g | ]}| j v r j | qS rI   )r  )rT   r  )r|   rI   rK   rV     s
    
c                   s6   g | ]\}}j d u s|j kr jt||dqS )Nr^  )r!  r  r   )rT   r   r-  )target_mapperrB  rI   rK   rV     s    

c                 S  s    g | ]}|d d |d fqS )r   rI   rU  rI   rI   rK   rV     s    r   c                 S  s"   g | ]}|t |t |fqS rI   )r   instance_stateinstance_dict)rT   r]  rI   rI   rK   rV     s    )	r  returned_defaults_rowsr[  r   r  r   r  r  r  )	r   r|   r   r   rB  r  pk_rowsr  objsrI   )r|   r  rB  rK   rF    s<   


z(BulkORMUpdate._do_post_synchronize_fetchc              	     s  |j j}t|}	| |}
| |
}i }|D ]\}}z|	tt	j
|}W n
 tjy5   Y qw |||< qt| dd |D }t } fdd|D }fdd|D }fdd|D }|D ]U\}}}| fdd|D  ||j| |j}|D ]}||v r|| |||< q|jj|d	| ||t| |||}|r||| || qm|| d	S )
zeapply values to objects derived from an update statement, e.g.
        UPDATE..SET <values>

        c                 S  s   h | ]\}}|qS rI   rI   r   rI   rI   rK   	<setcomp>5  rY   zDBulkORMUpdate._apply_update_set_values_to_objects.<locals>.<setcomp>c                   s.   h | ]}|j  v r|jv r|j vr|qS rI   )rf   ru  r   effective_paramsr  r:   rI   rK   r  9  s    


c                   s"   h | ]}| j v r j | jqS rI   ru  rf   r   rb   rI   rK   r  @  s
    

c                   s   g | ]} j | j|jfqS rI   r  r   rb   rI   rK   rV   F  s    zEBulkORMUpdate._apply_update_set_values_to_objects.<locals>.<listcomp>c                   s   i | ]	\}}| | qS rI   rI   )rT   col_to_propc_key)r  rI   rK   r   M  s    zEBulkORMUpdate._apply_update_set_values_to_objects.<locals>.<dictcomp>N)r  r   r   re  rs  rz  ri  r   r   r   r   rn  r   r   r   r  r  r  rR   r  r   r  r  r  r  add_register_altered)r   r|   rB  r   r  r  r  r  rj  rk  rx  resolved_keys_as_propnamesvalue_evaluatorsrf   value
_evaluatorattribr   to_prefetchr  prefetch_transferr]  rU   rX   r  rI   r  rK   r    sd   




z1BulkORMUpdate._apply_update_set_values_to_objects)r|   r0   r   r  rl   r5   r9   r+   r	  r.   rm   r3   rE   r  r  )r   r  r  r  r   r  r  r  r)  rG  rE  rF  r  r  rI   rI   r  rK   r    s*    
b$U$
*

5r  deletec                      s`   e Zd Zedd Zed$ fddZedddddd%ddZed d! Zed"d# Z  Z	S )&BulkORMDeletec                 K  sh  |  | }|jdd}|dks|dkr'd|jjvr'tj|||fi | |S |j }|}|jjd }|j |_}	|j||||d |	 }
|
jjd |	u rR|	j
|
_| |j|	}|r`|
j| }
tj||
|fi | d}|srd }n|jdd }|jdd }|dur|d	ko|j|j|	|j|jd
dd}|rd}|
j|
jj }
|r|j|||
|	|d}
|
|_|S )Nr,  r  r2  r   r  Fr/  r)  r6  r&  )r$  r&  Tr  )r  r   r   r`   r%   r  r  r:   r  r  r   rT  rR  r  r)  r(  r$  rA   r   r  r   )r   r   r   r  r   r,  r  r   r   r:   r  r  r   r/  r)  rI   rI   rK   r   m  sz   

z"BulkORMDelete.create_for_statementr|   r0   r   
dml.Deleterl   r5   r9   r+   r	  r.   rm   r3   rE   r  c                   sL   | d| j}|jdkrtd|jdvrtdt ||||||S )Nr*  rv   zBulk ORM DELETE not supported right now. Statement may be invoked at the Core level using session.connection().execute(stmt, parameters))r3  r  r2  zGValid strategies for ORM DELETE strategy are 'orm', 'auto', 'core_only')r   r"  r  r9  r:  r;  r  r  )r   r|   r   rl   r9   r	  rm   rB  r  rI   rK   r    s   


z#BulkORMDelete.orm_execute_statementFr#  r(  r   r:   r   r$  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 )NFr  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)delete_returningr   r  delete_returning_multifromr9  r  r   r  rI   rI   rK   r)    s   
zBulkORMDelete.can_use_returningc                 C  s^   |  ||j }g }|D ]\}}}	}
|
r||	|jj q|| q|r-|| d S d S rH   )rd  r  r  _expire	_modifiedr`  _remove_newly_deleted)r   r|   r   r   rB  r  	to_deleter  rU   rX   is_partially_expiredrI   rI   rK   rE    s   z+BulkORMDelete._do_post_synchronize_evaluatec                   s    j }|j}|r| |||} fdd|D }n j}|D ]&}	|	dd }
|	d }|jt|
|d}||jv rD|t	|j| g qd S )Nc                   r  rI   r  rU  r  rI   rK   rV   3  r  z<BulkORMDelete._do_post_synchronize_fetch.<locals>.<listcomp>r   r  r^  )
r  r  r[  r   r  r   r  r	  r   r  )r   r|   r   r   rB  r  r  r  r  rV  r   r-  r  rI   r  rK   rF  &  s4   

z(BulkORMDelete._do_post_synchronize_fetch)r|   r0   r   r  rl   r5   r9   r+   r	  r.   rm   r3   rE   r  r  )
r   r  r  r  r   r  r)  rE  rF  r  rI   rI   r  rK   r  k  s    
[(
r  )r:   r;   r<   r=   r>   r1   r?   r@   rA   r@   rB   r@   r8   rC   r9   rD   rE   rF   )r:   r;   r<   r=   r>   r1   r?   r@   rA   r@   rB   r@   r8   rN   r9   rD   rE   rO   )r:   r;   r<   r=   r>   r1   r?   r@   rA   r@   rB   r@   r8   rN   r9   rD   rE   rP   )r:   r   r<   r=   r>   r1   r?   r@   r   r@   r   rC   r   r@   rE   rF   )r:   r   r<   r=   r>   r1   r?   r@   r   r@   r   r   r   r@   rE   r   )r:   r   r<   r=   r>   r1   r?   r@   r   r@   r   r   r   r@   rE   r   )O__doc__
__future__r   typingr   r   r   r   r   r   r	   r
   r    r   r   r   r   rv  r   r   baser   r   r   r   r   r9  r   enginer   r   r   sqlr   r   r   r   r    r!   sql.baser"   r#   r$   sql.dmlr%   r&   r'   r(   util.typingr)   _typingr*   r+   r,   r:   r-   r|   r.   r/   r0   r1   rU   r2   r3   r4   engine.interfacesr5   objectr6   rL   r   r   r   r  
plugin_forr  r  r  rI   rI   rI   rK   <module>   s   			 \ x    

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