o
    )f                    @  sp  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		8	8dmdndIdJZFe		8	8dmdodMdJZF	N	NdpdqdPdJZFe		8	QdrdsdVdWZGe		8	QdrdtdZdWZG	N	Qdudvd\dWZGd]d^ ZHG d_d` d`eZIG dadb dbeIZJe*KdcddG dedf dfeIe.ZLe*KdcdgG dhdi dieJe/ZMe*KdcdjG dkdl dleJe-ZNdNS )wzoadditional 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.mapper
Mapper[_O]mappings<Union[Iterable[InstanceState[_O]], Iterable[Dict[str, Any]]]session_transactionr1   isstatesboolreturn_defaultsrender_nullsuse_orm_insert_stmtLiteral[None]execution_options$Optional[OrmExecuteOptionsParameter]returnNonec                 C     d S N r8   r:   r<   r=   r?   r@   rA   rC   rI   rI   \/var/www/html/flask-app/venv/lib/python3.12/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   W   rM   N"Optional[cursor.CursorResult[Any]]c                   s  j }|jjrtd|r&|rdd D }	dd |	D ndd D ndd D t || d }
fdd|j D }|rJd}nt|d	krSd}nd
}|D ]W\}}|d urj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|}
qW|jr|sJ |
|}
qW|r|rӈj}dd jD }|	D ]\}|tf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>x       z _bulk_insert.<locals>.<listcomp>c                 S  s   g | ]\}}|qS rI   rI   )rT   rU   dict_rI   rI   rK   rV   y       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r8   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
connectionr8   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    )bulkr?   r@   include_bulk_keys)bookkeepingrA   rC   c                 S  rZ   rI   re   )rT   prI   rI   rK   rV      r[   c                      g | ]} | qS rI   rI   rT   rf   )rX   rI   rK   rV      rY   )base_mappersessionconnection_callableNotImplementedError_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   )r8   r:   r<   r=   r?   r@   rA   rC   r|   statesreturn_resultmappers_to_runrx   r`   super_mapperextra_bp_namesrecordsr   identity_clsidentity_propsrU   rI   )rr   rX   r8   r:   rK   rL   d   s   







TMapper[Any]update_changed_onlyuse_orm_update_stmtenable_check_rowcountc                 C  rG   rH   rI   r8   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   )r8   rU   )r   )rU   rK   _changed_dict  s   z#_bulk_update.<locals>._changed_dictc                   s   g | ]} |qS rI   rI   rS   )r   r8   rI   rK   rV     rW   z _bulk_update.<locals>.<listcomp>c                 S  rZ   rI   rQ   rS   rI   rI   rK   rV     r[   c                 S  r\   rI   rQ   r]   rI   rI   rK   rV     rY   zJconnection_callable / per-instance sharding not supported in bulk_update()c                   rc   rd   re   rg   ri   rI   rK   rV   &  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   6  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)r8   r:   r<   r=   r   r   r   r|   r   r`   r   r   rI   )r   rr   r8   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_fnr{   composite_attrsrI   rK   r   ]  s    z&_expand_composites.<locals>.<dictcomp>)
compositessetkeysintersection)r8   r:   composite_keys
populatorsru   rf   rI   r   rK   r   W  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
isinstancestrr"   r   ExpressionElementRoler!   NullType_bulk_update_tuples_annotations)clsr8   	statementkv_iteratorneeds_to_be_cacheablecore_get_crud_kv_pairsr   r   desck_annoattrrI   rI   rK   _get_orm_crud_kv_pairsj  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   r8   r   )rT   
value_dictr   r   r   rI   rK   rV     s    z8ORMDMLState._get_multi_crud_kv_pairs.<locals>.<listcomp>)_propagate_attrsr8   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   r8   r'   r   listr   )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   r8   is_aliased_classr   class___name__r   local_table)r   r   ext_infor8   _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     s    z4ORMDMLState._setup_orm_returning.<locals>.<listcomp>supplemental_cols)r   r   rC   _execution_optionsoptions_with_optionsselect_statementr   create_for_statementr   !setup_dml_returning_compile_state	_generateprimary_columnsextendprimary_keyr?   	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  sT   |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   rC   bind_argumentsr   execution_contextr  load_optionsquerycontextrI   rI   rK   _return_orm_returning9  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   f  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                   @  sr   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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)r   r  r  r  r  r  r  r  r  r  r  r(   _resolved_values_eval_condition_matched_rows_identity_tokenrI   rI   rI   rK   default_update_options]  s   
 r"  Fis_multitableis_update_fromis_delete_usingis_executemanydialectr   r8   r   r$  r>   r%  r&  r'  rE   c                C  s   t  rH   )r   )r   r(  r8   r$  r%  r&  r'  rI   rI   rK   can_use_returningj  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&  synchronize_sessionclauser   F0statement had 'orm' plugin but no plugin_subjectr8   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', Falser5  zkThe 'fetch' synchronization strategy is not available for 'bulk' ORM updates (i.e. multiple parameter sets)r4  r  )r.  r&  r%  r,  r)  )r  r"  from_execution_optionsr   r   KeyErrorr8   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   rC   r
  is_pre_eventupdate_optionsr   syncrI   rI   rK   orm_pre_session_execw  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*  r2  r4  r5  rv   )r  r  _do_post_synchronize_evaluate_do_post_synchronize_fetch"_do_post_synchronize_bulk_evaluater  )r   r}   r   rl   rC   r
  r   rA  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   0  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   _adapterr8   r   _single_table_criterion)r   global_attributesr   return_critrI   )rN  r   rK   _adjust_for_extra_criteria  s"   
z-BulkUDCompileState._adjust_for_extra_criteriac                   s   |j |jj ur	|S dd |j jD  | D ]2}|jdu r n*|j |jj u r'qt|j|jj  }dd || D }  D ]
\}}||  |< q=q fddt|j jD fdd|jjD fdd|D S )	a  translate from local inherited table columns to base mapper
        primary key columns.

        Joined inheritance mappers always establish the primary key in terms of
        the base table.   When we UPDATE a sub-table, we can only get
        RETURNING for the sub-table's columns.

        Here, we create a lookup from the local sub table's primary key
        columns to the base table PK columns so that we can get identity
        key values from RETURNING that's against the joined inheritance
        sub-table.

        the complexity here is to support more than one level deep of
        inheritance, where we have to link columns to each other across
        the inheritance hierarchy.

        c                 S  s   i | ]}||qS rI   rI   )rT   pkrI   rI   rK   r   [  r[   z@BulkUDCompileState._interpret_returning_rows.<locals>.<dictcomp>Nc                 S  s   i | ]\}}||qS rI   rI   )rT   super_pksub_pkrI   rI   rK   r   d  rW   c                   s   i | ]	\}} | |qS rI   rI   )rT   idxlpk)local_pk_to_base_pkrI   rK   r   h  s    c                   rz   rI   rI   )rT   bpk)lookuprI   rK   rV   l  s    z@BulkUDCompileState._interpret_returning_rows.<locals>.<listcomp>c                   s"   g | ] t  fd dD qS )c                 3      | ]} | V  qd S rH   rI   )rT   rW  rowrI   rK   rs   o      zJBulkUDCompileState._interpret_returning_rows.<locals>.<listcomp>.<genexpr>)r   )rT   )primary_key_convertr]  rK   rV   o  s   " )	r   r|   r   iterate_to_rootinheritsrR   _table_to_equatedr   	enumerate)r   r8   rowsra   t_to_e
col_to_colrT  super_rI   )rY  r[  r`  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   )r8   r   expiredobjrR   rS   rb   rI   rK   rV   v  s    
zGBulkUDCompileState._get_matched_objects_on_criteria.<locals>.<listcomp>c                   s&   g | ]\}}}|j  kr|||fqS rI   r-  )rT   rk  rU   rX   rl  rI   rK   rV   ~  s
    
T)r  r  r!  r   _EXPIRED_OBJECTappend)
r   rA  r   eval_conditionraw_datar   rk  rU   rX   evaled_conditionrI   )r-  r8   rK    _get_matched_objects_on_criteriaq  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   )rk  rI   rI   rK   r    s   zJBulkUDCompileState._eval_condition_from_statement.<locals>._eval_condition)
r  r   r   _EvaluatorCompiler_where_criteriar   _is_criteria_optionget_global_criteriarS  process)r   rA  r   r8   
target_clsevaluator_compilerrM  rQ  optro  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.

        r4  )r  r  r  r5  )r|  r   UnevaluatableErrorr=  )r   r}   r   rl   rC   r
  rA  ro  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  )r|  r   r}  r8  r9  )	r   r}   r   rl   rC   r
  rA  ro  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   r8   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UnmappedColumnErrorrn  rf   r8  r9  )r   r8   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'  r8  r9  r   r   )r  bindper_bind_resultr)  r   r8   rA  rI   rK   skip_for_returning>  s,   
zHBulkUDCompileState._do_pre_synchronize_fetch.<locals>.skip_for_returning)rC   r
  
_add_event)r   r  )r  r/   rE   r   )
r  r    r   select_identity_tokenselect_fromr   r   ru  executefetchall)r   r}   r   rl   rC   r
  rA  select_stmtr  r   matched_rowsrI   r  rK   r=    s*   
!z,BulkUDCompileState._do_pre_synchronize_fetchNr(  r   r8   r   r$  r>   r%  r>   r&  r>   r'  r>   rE   r>   )r   r  r  r$   r"  r  r)  rC  rG  rS  ri  rr  r|  r;  r<  r  r  r=  rI   rI   rI   rK   r  \  s<    
w
+
$
0
&

/



r  r2  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  _populate_existing)
r   r  r  r  r  r  r  r  r  r  rI   rI   rI   rK   default_insert_optionsp  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,  r@   populate_existingr/  r   Fr0  r8   r  r  r  r2  rv   r3  rawr,  )r  r  r6  r   r   r7  r8   r  r8  r9  r   _orm_load_exec_optionsr   r  r>  r   r?  )	r   r}   r   rl   rC   r
  r@  insert_optionsr   rI   rI   rK   rC  z  sX   






z"BulkORMInsert.orm_pre_session_execr}   r0   r   
dml.Insertrl   r5   rC   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   r2  r  zHValid strategies for ORM insert strategy are 'raw', 'orm', 'bulk', 'autor  )rC   rv   z`bulk INSERT with a 'post values' clause (typically upsert) not supported for multi-table mapper Iterable[Dict[str, Any]]F)r=   r?   r@   rA   rC   r2  r  r  T)r   r  r  r8  r:  r  r  _post_values_clause_multiple_persistence_tablesr9  _transactionrL   r   r   rR   r  r  AssertionErrorr>   r   r  r   r  r   r  )r   r}   r   rl   rC   r
  rm   r  r   r8   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   r2  )
r   r  superr   stackr   r   r   _setup_for_bulk_insert_setup_for_orm_insert)r   r   r   kwr   toplevelr8   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   0  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   2  s    
z;BulkORMInsert._resolved_keys_as_col_keys.<locals>.<genexpr>)r   )r   r8   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   r8   r   r   rI   rI   rK   r  7  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   W  
    
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  r8  CompileError)r   r   r   r   anemit_insert_mapperrI   r  rK   r  C  s2   

	
z$BulkORMInsert._setup_for_bulk_insert)r}   r0   r   r  rl   r5   rC   r+   r
  r.   rm   r3   rE   r  )rE   r  )r   r  r  r$   r  r   r  r  rC  r  r   r  r  r  __classcell__rI   rI   r  rK   r  n  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   r1  r   )r2  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   t  s    

z"BulkORMUpdate.create_for_statementc                 K  s<  |}|j  }|jjd }|j | _}| ||| _| j||||d |jr+t| j| _|	 }|j
r7| j|_
n|jr>| j|_| | j|}	|	rL|j|	 }tj| ||fi | d}
|s^d }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)  r5  )r$  Tr  )r  r`   r   r8   r  r  _init_global_attributesr  rR   r  r  rS  rQ  wherer'   r  r   r)  r(  r$  r?   r   r  r   )r   r   r   r  r   r  r   r8   new_stmtnew_critr   r.  r)  rI   rI   rK   r    sf   



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  r  r8  r9  r  r   r   )r   r   r   r  r  _rI   r  rK   r    s"   

z$BulkORMUpdate._setup_for_bulk_updater}   r0   r   
dml.Updaterl   r5   rC   r+   r
  r.   rm   r3   rE   r  c              	     s   | d| j}|jdvrtd|jdkr_|j }|jdks!J |jr.|jdkr.td|j}	|	d us7J |j	d us>J t
|	tdt|trJ|gn||j	d	d	||d
}
| ||||||
S t ||||||S )Nr*  )r2  r  rv   r1  zOValid strategies for ORM UPDATE strategy are 'orm', 'auto', 'bulk', 'core_only'rv   r5  r4  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  r8  r:  ru  r  r9  r  r  r   r   r   rR   rG  r  r  )r   r}   r   rl   rC   r
  rm   rA  r   r8   r   r  rI   rK   r    s^   



	z#BulkORMUpdate.orm_execute_statementFr#  r(  r   r8   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_multifromr8  r  r   r   r(  r8   r$  r%  r&  r'  normal_answerrI   rI   rK   r)  Z  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  r\  rH   rI   r{   paramrI   rK   rs     r_  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   rA  r8   pk_keysr  identity_keyrU   evaluated_keysrX   to_evaluaterf   	to_expirerI   r  rK   rF    s:   

z0BulkORMUpdate._do_post_synchronize_bulk_evaluatec                 C  s0   |  ||j }| |||dd |D  d S )Nc                 S  s   g | ]\}}}}|||fqS rI   rI   )rT   rk  rU   rX   r  rI   rI   rK   rV     s    z?BulkORMUpdate._do_post_synchronize_evaluate.<locals>.<listcomp>)rr  r  
all_states#_apply_update_set_values_to_objects)r   r}   r   r   rA  matched_objectsrI   rI   rK   rD    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 }|s5d S |  |dd |D  d S )Nc                      g | ]
}t | jf qS rI   r   r!  rT   r^  rA  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 )Nrl  )r!  r  r   )rT   r   r-  )target_mapperrA  rI   rK   rV     s    

c                 S  s    g | ]}|d d |d fqS )r   rI   r  rI   rI   rK   rV     s    c                 S  s"   g | ]}|t |t |fqS rI   )r   instance_stateinstance_dict)rT   rk  rI   rI   rK   rV     s    )r  returned_defaults_rowsri  r   r  )	r   r}   r   r   rA  r   pk_rowsr  objsrI   )r}   r  rA  rK   rE    s6   

z(BulkORMUpdate._do_post_synchronize_fetchc              	   C  s.  |j }|j}t|}| ||}| ||}	i }
|	D ]\}}z|tt	j
|}W n
 tjy5   Y qw ||
|< qt|
 }dd |	D }t }|D ]B\}}}|j|}|D ]}||v rh|
| |||< qZ|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>	  rY   zDBulkORMUpdate._apply_update_set_values_to_objects.<locals>.<setcomp>N)r  r   r   rt  r  r  rx  r   r   r   r   r}  r   r   r   r  r   r  r  r  r  r  r  add_register_altered)r   r}   rA  r   r  r8   ry  rz  r  resolved_keys_as_propnamesvalue_evaluatorsrf   value
_evaluatorr  attribr   rk  rU   rX   r  r  rI   rI   rK   r    sB   

z1BulkORMUpdate._apply_update_set_values_to_objects)r}   r0   r   r  rl   r5   rC   r+   r
  r.   rm   r3   rE   r  r  )r   r  r  r  r   r  r  r  r)  rF  rD  rE  r  r  rI   rI   r  rK   r  r  s*    
_$K$
*

3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  sP  |  | }|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|	}|rT|
j| }
tj||
|fi | d}|sfd }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  r1  r   r  Fr.  r)  r5  r&  )r$  r&  Tr  )r  r   r   r`   r%   r  r  r8   r  r  rS  rQ  r  r)  r(  r$  r?   r   r  r   )r   r   r   r  r   r,  r  r   r   r8   r  r  r   r.  r)  rI   rI   rK   r   %  sv   

z"BulkORMDelete.create_for_statementr}   r0   r   
dml.Deleterl   r5   rC   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))r2  r  r1  zGValid strategies for ORM DELETE strategy are 'orm', 'auto', 'core_only')r   r"  r  r8  r9  r:  r  r  )r   r}   r   rl   rC   r
  rm   rA  r  rI   rK   r  ~  s   


z#BulkORMDelete.orm_execute_statementFr#  r(  r   r8   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_multifromr8  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   )rr  r  r  _expire	_modifiedrn  _remove_newly_deleted)r   r}   r   r   rA  r  	to_deleter  rU   rX   is_partially_expiredrI   rI   rK   rD    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 rC|t	|j| g qd S )Nc                   r  rI   r  r  r  rI   rK   rV     r  z<BulkORMDelete._do_post_synchronize_fetch.<locals>.<listcomp>r   r  rl  )
r  r   ri  r   r  r   r  r  r   r  )r   r}   r   r   rA  r  r   r  r  r^  r   r-  r  rI   r  rK   rE    s4   

z(BulkORMDelete._do_post_synchronize_fetch)r}   r0   r   r  rl   r5   rC   r+   r
  r.   rm   r3   rE   r  r  )
r   r  r  r  r   r  r)  rD  rE  r  rI   rI   r  rK   r  #  s    
X(
r  )..)r8   r9   r:   r;   r<   r1   r=   r>   r?   r>   r@   r>   rA   rB   rC   rD   rE   rF   )r8   r9   r:   r;   r<   r1   r=   r>   r?   r>   r@   r>   rA   rN   rC   rD   rE   rO   )NN)r8   r9   r:   r;   r<   r1   r=   r>   r?   r>   r@   r>   rA   rN   rC   rD   rE   rP   ).T)r8   r   r:   r;   r<   r1   r=   r>   r   r>   r   rB   r   r>   rE   rF   )r8   r   r:   r;   r<   r1   r=   r>   r   r>   r   r   r   r>   rE   r   rs  )r8   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   r  r   r   baser   r   r   r   r   r8  r   enginer   r   r   sqlr   r   r   r   r    r!   sql.baser"   r#   r$   sql.dmlr%   r&   r'   r(   util.typingr)   _typingr*   r+   r,   r8   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   	 [ w    
  
   
3