U kf @sdZddlmZddlmZddlmZddlmZddlmZddlmZddlm Z dd lm Z dd lm Z dd lm Z d d l mZd dl mZd dl mZd dl mZd dl mZd dl mZd dlmZd dlmZd dlmZd dlmZd dlmZddl mZddl mZddlmZddlmZ ddl!m"Z"ddl!m#Z#ddl!m$Z$ddl!m%Z%dd l!m&Z&dd!l!m'Z'dd"l(m)Z)dd#l(m*Z*dd$l(m+Z+dd%l,m-Z-dd&l,m.Z.dd'l,m/Z/dd(lm0Z0dd)l1m2Z2e rnd d*l3m4Z4d d+l3m5Z5d d,l3m6Z6d d-l7m8Z8d d.l9m:Z:d d/l9m;Z;d d0l9mm?Z?dd3lm@Z@dd4lmAZAdd5lBmCZCe d6eDd7ZEe d8d8d9d:d;dd?d@dA dBdCZFe d8d8d9d:d;dd=d@dMdNdOZGe d8dJdKdLd;dr?r@rAr8r9rDrDO/opt/hc_python/lib64/python3.8/site-packages/sqlalchemy/orm/bulk_persistence.py _bulk_insertJs rGzOptional[dml.Insert]zcursor.CursorResult[Any]cCsdSrCrDrErDrDrFrGXs Nz"Optional[cursor.CursorResult[Any]]c sj}|jjrtd|rbtr0tttt|rRddD} dd| DqddDn@tr|ttt t t f|rt nddDt ||d} fdd|jD} |rd} nt| d krd} nd } | D]\} }|dk rfd d|Dnd }fd dtj| fddDd| ||dD}tj|d|| || ||d}|dk r|jr| dkr|} q|jr| st| |} q|r|rj}ddjD}| D](\}|tfdd|Ddf|_q|dk r| dk s t| SdS)NzJconnection_callable / per-instance sharding not supported in bulk_insert()cSsg|]}||jfqSrDdict.0staterDrDrF sz _bulk_insert..cSsg|] \}}|qSrDrD)rKrLdict_rDrDrFrMscSsg|] }|jqSrDrHrJrDrDrFrMscSsg|] }t|qSrDrHrKmrDrDrFrMscs"g|]\}}|jkr||fqSrD) _pks_by_table)rKtablempr<rDrFrMs Tr Fcs g|]}|jdkr|jqSrkeyrKbr=rDrFrMsrDc 3s2|]*\}}}}}}}}d|||||fVqdSrCrD) rKrLZ state_dictparamsrSconnZ value_paramsZ has_all_pksZhas_all_defaults connectionr<rDrF s$ z_bulk_insert..c3s|]}d|fVqdSrCrDrKmappingr]rDrFr_s)bulkr@rAinclude_bulk_keys) bookkeepingr8r9cSsg|] }|jqSrDrV)rKprDrDrFrMscsg|] }|qSrDrDrKrW)rNrDrFrMs) base_mappersessionconnection_callableNotImplementedErrorr rrr2r6rstrrlist_expand_compositesr^_sorted_tablesitemslen_get_embedded_bindparamsrZ_collect_insert_commandsZ_emit_insert_statements _returningZ returns_rowsAssertionErrorZsplice_horizontallyZ_identity_class_identity_key_propstuplerW)r<r=r>r?r@rAr8r9rgstatesZ return_resultZmappers_to_runrdrR super_mapperextra_bp_namesrecordsrZ identity_clsZidentity_propsrLrD)r^rNr<r=rFrGfs               T)use_orm_update_stmtenable_check_rowcount Mapper[Any])r<r=r>r?update_changed_onlyrzr{rBcCsdSrCrDr<r=r>r?r}rzr{rDrDrF _bulk_updates rzOptional[dml.Update]z_result.Result[Any]cCsdSrCrDr~rDrDrFr s zOptional[_result.Result[Any]]c s0j}jjr"jjhfdd|r\|rLfddDqtddDnddDt|jjrtd| ||dk rfdd| Dnd }|j D]^\} }  | r| jkrqtjd| fd d Dd ||d } tj|d| | | d||dq|dk r,tSdS)NcsfddjDS)Ncs(i|] \}}|jks|kr||qSrD)Zcommitted_staterKkv) search_keysrLrDrF )s  z7_bulk_update.._changed_dict..)rIro)r<rL)r)rLrF _changed_dict(s z#_bulk_update.._changed_dictcsg|]}|qSrDrDrJ)rr<rDrFrM1sz _bulk_update..cSsg|] }|jqSrDrHrJrDrDrFrM3scSsg|] }t|qSrDrHrOrDrDrFrM5szJconnection_callable / per-instance sharding not supported in bulk_update()cs g|]}|jdkr|jqSrUrVrXrZrDrFrMCsrDc3s.|]&}d|jr |jjndfVqdSrC)_version_id_proprWr`r]rDrFr_Ss z_bulk_update..T)rbrzrcF)rdrzr{)rgZ_primary_key_propkeysrrWunionrmrhrirjr^rqrnroisarQrZ_collect_update_commandsZ_emit_update_statements_result null_result) r<r=r>r?r}rzr{rgrxrRrwryrD)rr^r<r=rrFrs^        csV|jsdSt}fdd|D}|D] }||D]}|||q>q0dS)Ncsi|]}||qSrD)Z)_populate_composite_bulk_save_mappings_fnrfZcomposite_attrsrDrFrzsz&_expand_composites..)Z compositessetkeys intersection)r<r=Zcomposite_keysZ populatorsrarWrDrrFrmts  rmc@steZdZUdZdZded<eddZeddZed d Z ed d Z ed dZ ddddZ eddZ dS) ORMDMLStateTNz&Optional[ORMFromStatementCompileState]from_statement_ctxc cstj}|D]\}}ttj|}t|trt||t d}|t krrttj||rhtjtj |t ddn|fVq||| ||EdHq d|jkr|j} t| d| d} ||| ||EdHq ||s|ntjtj |t ddfVq dS)N)defaultT)type_Zis_crudZentity_namespace proxy_key)r'_get_crud_kv_pairsrexpectrZ DMLColumnRole isinstancerkr"rExpressionElementRoler!ZNullTypeZ_bulk_update_tuples _annotations) clsr< statement kv_iteratorneeds_to_be_cacheableZcore_get_crud_kv_pairsrrdescZk_annoattrrDrDrF_get_orm_crud_kv_pairssT      z"ORMDMLState._get_orm_crud_kv_pairscs6jdrjs t|Sfdd|DS)Nplugin_subjectc s&g|]}tj|dqS)F)rIrr<ro)rKZ value_dictrrrrDrFrMsz8ORMDMLState._get_multi_crud_kv_pairs..)_propagate_attrsr<r'_get_multi_crud_kv_pairs)rrrrDrrFrs  z$ORMDMLState._get_multi_crud_kv_pairscCsD|s td|jd}|r |js.t|||St||j|||S)Nz0no test coverage for needs_to_be_cacheable=Falser)rsrr<r'rrlr)rrrrrrDrDrFrs&  zORMDMLState._get_crud_kv_pairscCs@|jjd}|j}|jr |j}n|jj}||j|j|j|jdS)N parententity)nametypeexprentityrR) rRrr<is_aliased_classrclass___name__r local_table)rrext_infor<Z _label_namerDrDrFget_entity_descriptions z"ORMDMLState.get_entity_descriptioncs2ddddfddfdd|jDDS)NcSs|jddS)Nr)rget)crDrDrF _ent_for_colszCORMDMLState.get_returning_column_descriptions.._ent_for_colcSs4|dkr |S|jdd}|s"|St|j||SdS)Nr)rrgetattrr)rentrrDrDrF _attr_for_cols zDORMDMLState.get_returning_column_descriptions.._attr_for_colcs.g|]&\}}|j|j|||j|jdqS))rrraliasedr)rWrrr)rKrr)rrDrFrMszAORMDMLState.get_returning_column_descriptions..csg|]}||fqSrDrDrKr)rrDrFrMs)Z_all_selected_columns)rrrD)rrrF!get_returning_column_descriptionss  z-ORMDMLState.get_returning_column_descriptions)use_supplemental_colsc Cs|jrt|j|dd}|jf|j}|j|j}||_t|||_ }| || }d|_dd|j D}|s| |j|r|j|jd|i}n |j|}|S)alestablish 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_namesrDcSsg|]}|dk r|qSrCrDrrDrDrFrM8sz4ORMDMLState._setup_orm_returning..Zsupplemental_cols)rrrr9_execution_optionsoptions _with_optionsselect_statementrcreate_for_statementrZ!setup_dml_returning_compile_stateZ _generateZprimary_columnsextend primary_keyr@Z returning) selfcompilerorm_level_statementZdml_level_statement dml_mapperrfsZfscZcols_to_returnrDrDrF_setup_orm_returnings6      z ORMDMLState._setup_orm_returningc CsX|j}|jj}|jrP|jjjsP|dtj} t|j|j ||| ||} t || S|SdS)N_sa_orm_load_options) rcompiled compile_statercompile_options_is_starrrdefault_load_optionsrrZ instances) rrhrr[r9bind_argumentsrZexecution_contextr load_optionsZ querycontextrDrDrF_return_orm_returningVs*  z!ORMDMLState._return_orm_returning)r __module__ __qualname__Zis_dml_returningr__annotations__ classmethodrrrrrrrrDrDrDrFrs   7    ! Crc @seZdZGdddeZedddddddddddddd d Zed d Zed dZeddZ eddZ eddZ eddZ eddZ eddZeddZeddZedd Zd!S)"BulkUDCompileStatec@sreZdZUdZded<dZded<dZded<dZded <dZded <d Z ded <d Z ded<e Z d Z d Zd Zd S)z)BulkUDCompileState.default_update_optionsautor* _dml_strategyr,_synchronize_sessionFr:_can_use_returning_is_delete_using_is_update_fromT _autoflushNOptional[Mapper[Any]]_subject_mapper)rrrrrrrrrrrr(_resolved_values_eval_condition _matched_rows_identity_tokenrDrDrDrFdefault_update_optionszs        rF is_multitableis_update_fromis_delete_usingis_executemanyrr|r:dialectr<rrrrrBcCs tdSrC)rj)rrr<rrrrrDrDrFcan_use_returnings z$BulkUDCompileState.can_use_returningc Cstjdddddddh||j\}}||d<z|jd }Wn tk rZd sVtd YnX|rx|j|d <|d |ji7}d|jj kr|ddi7}nNt |t s|j dkr|ddi7}q|j dkrt dn|j dkr|ddi7}|j} | dk r$| dkrt d|j dkr$| dkr$t d|s|jr:||j dkr|jdkrh|||||||}nB|jdkr|||||||}n |jdkr|||||||}n$|j dkr|jdkr|ddi7}||j|j|j|j |jd}|t|d|ifS)N_sa_orm_update_optionssynchronize_session autoflushidentity_tokenrr dml_strategyclauserF0statement had 'orm' plugin but no plugin_subjectr<rrr core_onlyrormrbHCan't use "bulk" ORM insert strategy without passing separate parameters)revaluatefetchFzSValid strategies for session synchronization are 'auto', 'evaluate', 'fetch', FalserzkThe 'fetch' synchronization strategy is not available for 'bulk' ORM updates (i.e. multiple parameter sets)rr)rrrrr)rrfrom_execution_optionsrrKeyErrorrsr<rRrrrlrsa_excInvalidRequestErrorr ArgumentErrorr_do_pre_synchronize_auto_do_pre_synchronize_evaluate_do_pre_synchronize_fetch _annotaterrrr immutabledictr) rrhrr[r9r is_pre_eventupdate_optionsrsyncrDrDrForm_pre_session_execs                   z'BulkUDCompileState.orm_pre_session_execcCs|d}|jdkrJ|jdkr.|||||qr|jdkrr|||||n(|jdkrr|jdkrn||||||S|||||||S)Nrrrrrb)rr_do_post_synchronize_evaluate_do_post_synchronize_fetch"_do_post_synchronize_bulk_evaluater)rrhrr[r9rrrrDrDrForm_setup_cursor_result sB     z*BulkUDCompileState.orm_setup_cursor_resultcs~d}jrjnddjf|krF|tfdd|djfD7}jjdk r`|jjf7}rztfdd|D}|S)aApply 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. rDNZadditional_entity_criteriac3s(|] }|js|jkr|VqdSrC)Zinclude_aliasesrZ_resolve_where_criteria)rKZae)rrDrFr_Ms z@BulkUDCompileState._adjust_for_extra_criteria..c3s|]}|VqdSrC)traverse)rKcrit)adapterrDrFr_Ys)rZ_adapterr<ruZ_single_table_criterion)rglobal_attributesrZ return_critrD)r rrF_adjust_for_extra_criteria8s"   z-BulkUDCompileState._adjust_for_extra_criteriacs|j|jjk r|Sdd|jjD|D]f}|jdkr@qn|j|jjkrPq,t|j|jj}dd||D}D]\}}|||<q|q,fddt|jjDfdd|jjDfdd|DS) atranslate 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. cSsi|] }||qSrDrD)rKpkrDrDrFrxsz@BulkUDCompileState._interpret_returning_rows..NcSsi|]\}}||qSrDrD)rKZsuper_pkZsub_pkrDrDrFrscsi|]\}}||qSrDrD)rKidxZlpk)local_pk_to_base_pkrDrFrscsg|] }|qSrDrD)rKZbpk)lookuprDrFrMsz@BulkUDCompileState._interpret_returning_rows..cs"g|]tfddDqS)c3s|]}|VqdSrCrD)rKrrowrDrFr_szJBulkUDCompileState._interpret_returning_rows...)ru)rK)primary_key_convertrrFrMs) rrgrZiterate_to_rootZinheritsrIZ_table_to_equatedro enumerate)rr<rowsrSZt_to_eZ col_to_colr Zsuper_rD)rrrrF_interpret_returning_rows]s&     z,BulkUDCompileState._interpret_returning_rowsc s|j|j}fdd|D}|jdk r>fdd|D}g}|D]<\}}}||} | dksj| tjkrF||||| tjkfqF|S)Ncs.g|]&}|jr|js|||jfqSrD)r<rZexpiredobjrIrJrTrDrFrMs zGBulkUDCompileState._get_matched_objects_on_criteria..cs&g|]\}}}|jkr|||fqSrDr)rKrrLrNrrDrFrMs T)rrrrZ_EXPIRED_OBJECTappend) rrrveval_conditionraw_datarrrLrNZevaled_conditionrD)rr<rF _get_matched_objects_on_criterias2  z3BulkUDCompileState._get_matched_objects_on_criteriac Cs~|j}|j}t|}d}|jr*||j7}i}|jD]}|jr4||q4|r^||||7}|rn|j |} n dd} | } | S)NrDcSsdS)NTrD)rrDrDrFrszJBulkUDCompileState._eval_condition_from_statement.._eval_condition) rrr_EvaluatorCompiler_where_criteriarZ_is_criteria_optionZget_global_criteriar process) rrrr< target_clsevaluator_compilerr r optrrrDrDrF_eval_condition_from_statements"     z1BulkUDCompileState._eval_condition_from_statementcCsVz|||}Wntjk r&YnX||ddS|ddi7}|||||||S)asetup 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)rrrr)r#rUnevaluatableErrorr)rrhrr[r9rrrrDrDrFrs( z+BulkUDCompileState._do_pre_synchronize_autoc CsRz|||}Wn4tjk rD}ztd||W5d}~XYnX|d|iS)Nz{Could not evaluate current criteria in Python: "%s". Specify 'fetch' or False for the synchronize_session execution option.r)r#rr$rr) rrhrr[r9rrrerrrDrDrFrs" z/BulkUDCompileState._do_pre_synchronize_evaluatecCs6|jr gS|jrt|jS|jr.t|jSgSdSrC)Z _multi_values_ordered_valuesrl_valuesro)rr<rrDrDrF_get_resolved_valuess z'BulkUDCompileState._get_resolved_valuesc Cslg}|D]^\}}|rXt|tjrXz|j|}Wntjk rDYqfX||j|fqt d|q|S)NzCAttribute name not found, can't be synchronized back to objects: %r) rrZ ColumnElementZ_columntopropertyorm_excZUnmappedColumnErrorrrWrr)rr<resolved_valuesvaluesrrrrDrDrF_resolved_keys_as_propnames's z.BulkUDCompileState._resolved_keys_as_propnamesc svjtjjfj|j}|j|_ddddfdd }|j|||||d} | } | dS)Nr/r) orm_contextrBcsv|jjf|j}j|jjj|jd}dk rH|krbt dn|jr^|s^t dn||rnt SdSdS)N)rrrzjFor 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) rhZget_bindrrrrrrrrrr)r-bindZper_bind_resultrrr<rrDrFskip_for_returning[s* zHBulkUDCompileState._do_pre_synchronize_fetch..skip_for_returning)r9rZ _add_event)rr) rr rZselect_identity_token select_fromrrrexecuteZfetchall) rrhrr[r9rrZ select_stmtr0r matched_rowsrDr/rFr9s, !z,BulkUDCompileState._do_pre_synchronize_fetchN)rrrr$rrrrrr rrr#rrr(r,rrDrDrDrFrys:   w + $ 0 &  /   rrinsertc seZdZUGdddeZdZded<eddZedd d d d d ddddZ eddfdd Z eddZ ddZ ddZ ZS) BulkORMInsertc@sVeZdZUdZded<dZded<dZded<dZd ed <d Zded <dZ ded <dS)z$BulkORMInsert.default_insert_optionsrr*rFr: _render_nulls_return_defaultsNrrTr_populate_existing) rrrrrr6r7rrr8rDrDrDrFdefault_insert_optionss      r9NzOptional[FromStatement]rc Cstjdddddh||j\}}||d<z|jd}Wn tk rVdsRtd YnX|rt|j|d <|d |ji7}|s|jd kr|d di7}q|jdkrt dn|jd kr|d di7}|jdkr|st j }n | t j }|s|jr||d|ji}|t| d|ifS)N_sa_orm_insert_optionsrrZpopulate_existingrArrFrr<rrrrrbrraw)r5r9rrrrrsr<rrrrZ_orm_load_exec_optionsrrrrr) rrhrr[r9rrinsert_optionsrrDrDrFrsT          z"BulkORMInsert.orm_pre_session_execr0z dml.Insertr5r+r.r3_result.Resultrhrr[r9rr\rBc Cs<|d|j}|jdkr"td|jdkrD|j||p8i|d}|S|jdkr|j} |jdk rt| jrtt d| | dk st |j dk st t | t dt|tr|gn||j d |j|j||d }n&|jd kr|j||pi|d}nt t|js|S|jr(|d tj} | d di7} |d | i}|||||||S)Nr:)r;rbrrzHValid strategies for ORM insert strategy are 'raw', 'orm', 'bulk', 'autor;)r9rbz`bulk INSERT with a 'post values' clause (typically upsert) not supported for multi-table mapper Iterable[Dict[str, Any]]F)r?r@rAr8r9rrr8T)rr9rrrr2rZ_post_values_clauseZ_multiple_persistence_tablesrrs _transactionrGrrrIr7r6r:rrr8rrrr) rrhrr[r9rr\r<rr<rrDrDrForm_execute_statements        z#BulkORMInsert.orm_execute_statement)rBc sztttj||f|}|dk r*|j }nd}|s6|S|jd}|jdd}|dkrb||n|dkrv| |||S)NTrrr;rbr) rr5superrstackrrr_setup_for_bulk_insert_setup_for_orm_insert)rrrkwrtoplevelr<r __class__rDrFr4s     z"BulkORMInsert.create_for_statementcs ddfdd|DDS)NcSs&i|]\}}}|dk r|jn||qSrCrV)rKcolrrrDrDrFrMsz.c3s$|]\}}j|||fVqdSrC)rrrrTrDrFr_Osz;BulkORMInsert._resolved_keys_as_col_keys..)ro)rr<Zresolved_value_dictrDrTrF_resolved_keys_as_col_keysKs  z(BulkORMInsert._resolved_keys_as_col_keyscCs0ttj|j}}|j||||dd}||_dS)NFrr)rrInsertrr)rrr<rrrDrDrFrETsz#BulkORMInsert._setup_for_orm_insertcsttj|j}}|j}|d|d}|}|_|jrXfdd|jD|_|j ||||dd}|j dk r|j j j rt d||_dS) 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_mappercs i|]\}}|jkr||qSrDrRrKrJvalZemit_insert_tablerDrFrts z8BulkORMInsert._setup_for_bulk_insert..TrLNzCan't use RETURNING * with bulk ORM INSERT. Please use a different INSERT form, such as INSERT..VALUES or INSERT with a Core Connection)rrrMrr_clonerR_dict_parametersrorrrrr CompileError)rrrranZemit_insert_mapperrDrQrFrD`s4  z$BulkORMInsert._setup_for_bulk_insert)rrrr$r9rrrrrArrKrErD __classcell__rDrDrHrFr5s   CX  r5updatec seZdZeddZddZddZeddd d d d d dfdd ZedddddddddddddddZeddZ eddZ eddZ edd Z Z S)! BulkORMUpdatecKs||}|jdd}|j }|r:|dkr:|||nH|dksV|dkrjd|jjkrjtj|||f|n|rv|dkr||||S)Nr unspecifiedrbrr)rrY) __new__rrrC_setup_for_bulk_updaterRr'__init___setup_for_orm_update)rrrrFrrrGrDrDrFrs$     z"BulkORMUpdate.create_for_statementc KsZ|}|j }|jjd}|j|_}||||_|j||||d|jrVt|j|_| }|jjd|krv|j |_|j r|j|_ n|jr|j|_| |j |} | r|j| }tj|||f|d} |sd} n|jdd} |jdd} | dk r| dko|j|j||jd} | dkr6| r6d} |j|jj}|rP|j||||| d }||_dS) NrrGZprocess_criteria_for_toplevelFrrr)rTrL)rCrRrr<r(r_init_global_attributesr'rIrRrr&r r wherer'r\rrrrr@rrr) rrrrFrrGrr<new_stmtnew_critrrrrDrDrFr]st        z#BulkORMUpdate._setup_for_orm_updatec s~ttj|}|j}|d|d}|}|_tj|||f||jrTt d|j rtfdd|j D|_ ||_ dS)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().cs i|]\}}|jkr||qSrDrNrOZemit_update_tablerDrFr's z8BulkORMUpdate._setup_for_bulk_update..N)rrZUpdaterrRrRr'r\r&rrrSror)rrrrFrU_rDrcrFr[ s"  z$BulkORMUpdate._setup_for_bulk_updater0z dml.Updater5r+r.r3r=r>c s|d|j}|jdkr"td|jdkr|j }|jdksBt|jr\|jdkr\td|j } | dk snt|j dk s|tt | t dt |tr|gn||j d d ||d } ||||||| St||||||SdS) Nr)rrrbrzOValid strategies for ORM UPDATE strategy are 'orm', 'auto', 'bulk', 'core_only'rbrrzbulk 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}rzr{)rrrrrrrrsrrr@rrrrIrrBrA) rrhrr[r9rr\rr{r<rrHrDrFrA.sb      z#BulkORMUpdate.orm_execute_statementFrrr|r:rcCsL|jo |jj}|sdS|r |jS|r*|jS|rH|jsHtd|jddS)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)Zupdate_returningrimplicit_returningZupdate_executemany_returningZupdate_returning_multifromrrTrrrr<rrrrZ normal_answerrDrDrFrzs   zBulkORMUpdate.can_use_returningcs|sdS|j}dd|jD}|j}|D]|fdd|D|j}||} | sXq(t|} | j} | j | } | D]} | | kr|| | | <q|| j j | d| | | t| | | | }|r(| | |q(dS)NcSsg|] }|jqSrDrV)rKproprDrDrFrMszDBulkORMUpdate._do_post_synchronize_bulk_evaluate..c3s|]}|VqdSrCrDrfparamrDrFr_szCBulkORMUpdate._do_post_synchronize_bulk_evaluate..)rrt identity_mapidentity_key_from_primary_keyrZfast_get_stater differencerI unmodifiedrmanagerdispatchrefresh_commitrl_expire_attributes)rrhr[rrr<Zpk_keysrk identity_keyrLevaluated_keysrN to_evaluaterW to_expirerDrirFrs4   z0BulkORMUpdate._do_post_synchronize_bulk_evaluatecCs0|||j}||||dd|DdS)NcSsg|]\}}}}|||fqSrDrD)rKrrLrNrdrDrDrFrMs z?BulkORMUpdate._do_post_synchronize_evaluate..)rrk all_states#_apply_update_set_values_to_objects)rrhrrrmatched_objectsrDrDrFrs z+BulkORMUpdate._do_post_synchronize_evaluatec sj|j}|r0||}fdd|D}nj}fddfdddd|DDD}|sjdS||dd|DdS)Ncsg|]}t|jfqSrDrurrKrrrDrFrMsz.cs g|]}|jkrj|qSrD)rk)rKrt)rhrDrFrMs cs6g|].\}}jdks |jkrjt||dqS)Nr)rrlrl)rKrr) target_mapperrrDrFrMs  cSs g|]}|dd|dfqS)rrDr|rDrDrFrMscSs"g|]}|t|t|fqSrD)r instance_state instance_dict)rKrrDrDrFrMs )rreturned_defaults_rowsrrry) rrhrrrrpk_rowsr3ZobjsrD)rhr~rrFrs8   z(BulkORMUpdate._do_post_synchronize_fetchc Cs2|j}|j}t|}|||}|||} i} | D]@\} } z|tt j | } Wntj k rlYq6X| | | <q6t | }dd| D}t}|D]\}}}|j|}|D]} | |kr| | ||| <q|jj|d|||t ||||}|r|||||q||dS)zeapply values to objects derived from an update statement, e.g. UPDATE..SET cSsh|] \}}|qSrDrDrrDrDrF )szDBulkORMUpdate._apply_update_set_values_to_objects..N)rrrrr(r,rrrrrr$rlrrrnrrorprqrrrmrsaddZ_register_altered)rrhrrrzr<r r!r*Zresolved_keys_as_propnamesZvalue_evaluatorsrWvalueZ _evaluatorruZattribrvrrLrNrvrwrDrDrFrys@         z1BulkORMUpdate._apply_update_set_values_to_objects)rrrrrr]r[rArrrrryrVrDrDrHrFrXs( b$ K $ *  3rXdeletec seZdZeddZeddddddd d fd d Zed d d d dddddddddddZeddZeddZZ S) BulkORMDeletecKsh||}|jdd}|dks4|dkrJd|jjkrJtj|||f||S|j }|}|jjd}|j|_} |j||||d| } | jjd| kr| j | _| |j | } | r| j | } tj|| |f|d} |sd} n|jdd} |jdd}|dk r,| d ko*|j|j| |j|jd dd }|rDd } | j| jj} |r^|j||| | | d } | |_|S)NrrYrrr^Frrrr)rrTrL)rZrrrRr%r\rCr<r_rRrr r r`rrrr@rrr)rrrrFrrrGrrr<rarbrrrrDrDrFrEs        z"BulkORMDelete.create_for_statementr0z dml.Deleter5r+r.r3r=r>csL|d|j}|jdkr"td|jdkr6tdt||||||S)NrrbzBulk ORM DELETE not supported right now. Statement may be invoked at the Core level using session.connection().execute(stmt, parameters))rrrzGValid strategies for ORM DELETE strategy are 'orm', 'auto', 'core_only')rrrrrrrBrA)rrhrr[r9rr\rrHrDrFrAs(   z#BulkORMDelete.orm_execute_statementFrrr|r:rcCsB|jo |jj}|sdS|r |jS|r>|js>td|jddS)NFrez" 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)Zdelete_returningrrfZdelete_returning_multifromrrTrrgrDrDrFrs   zBulkORMDelete.can_use_returningc CsZ|||j}g}|D],\}}} } | r<|| |jjq||q|rV||dSrC)rrkrxZ_expireZ _modifiedr_remove_newly_deleted) rrhrrrrzZ to_deleterdrLrNZis_partially_expiredrDrDrFrs z+BulkORMDelete._do_post_synchronize_evaluatec sj}|j}|r0|||}fdd|D}nj}|D]L} | dd} | d} |jt| | d} | |jkr:|t |j| gq:dS)Ncsg|]}t|jfqSrDr{r|r}rDrFrM sz.rrr) rrrrrlrlrkrr r) rrhrrrr~rrr3rrrrtrDr}rFrs2   z(BulkORMDelete._do_post_synchronize_fetch) rrrrrrArrrrVrDrDrHrFrCs [  ( r)O__doc__ __future__rtypingrrrrrrr r r r rrrr)rrbaserrrrrrrZenginerrrsqlrrrrr r!Zsql.baser"r#r$Zsql.dmlr%r&r'r(Z util.typingr)Z_typingr*r+r,r<r-rhr.r/r0r1rLr2r3r4Zengine.interfacesr5objectr6rGrrmrrZ plugin_forr5rXrrDrDrDrF s                                                     $  $"" " \w  6