B 4]t@sdZddlmZddlmZddlZddlmZddlmZddlmZ dd lm Z dd lm Z dd l m Z dd l mZd dlmZd dlmZd dlmZd dlmZd dlmZddZddZdTddZddZddZddZdd Zd!d"ZdUd#d$ZdVd%d&Zd'd(Zd)d*Z dWd,d-Z!dXd.d/Z"d0d1Z#d2d3Z$d4d5Z%d6d7Z&d8d9Z'd:d;Z(dd?Z*d@dAZ+GdBdCdCe,Z-GdDdEdEe-Z.GdFdGdGe-Z/GdHdIdIe-Z0GdJdKdKe-Z1GdLdMdMe.e0Z2GdNdOdOe.e1Z3GdPdQdQe/e0Z4GdRdSdSe/e1Z5dS)Yzprivate module containing functions used to emit INSERT, UPDATE and DELETE statements on behalf of a :class:`.Mapper` and its descending mappers. The functions here are called only by the unit of work functions in unitofwork.py. )chain)groupbyN) attributes) evaluator)exc)loading)sync)_entity_descriptor) state_str)sql)util) expression) _from_objectsc s&j}t|}|jjrtd|rT|rDdd|D}dd|D}q\dd|D}nt|}||xj|jD]\\} }  | sqrfddt | fdd|Dd ||d D} t |d|| | | |d qrW|r"|r"j } d dj D} x,|D]$\}| tfd d| Df|_qWdS)NzJconnection_callable / per-instance sharding not supported in bulk_insert()cSsg|]}||jfqS)dict).0staterrM/opt/alt/python37/lib64/python3.7/site-packages/sqlalchemy/orm/persistence.py 7sz _bulk_insert..cSsg|] \}}|qSrr)rrdict_rrrr8scSsg|] }|jqSr)r)rrrrrr:sc 3s2|]*\}}}}}}}}d|||||fVqdS)Nr) rr state_dictparamsZmpconn value_params has_all_pkshas_all_defaults) connectionmapperrr Ds z_bulk_insert..c3s|]}d|fVqdS)Nr)rmapping)rrrrr YsT)bulkreturn_defaults render_nulls) bookkeepingcSsg|] }|jqSr)key)rprrrrkscsg|] }|qSrr)rr&)rrrros) base_mapper_cached_connection_dictsessionconnection_callableNotImplementedErrorlistr_sorted_tablesitemsisa_collect_insert_commands_emit_insert_statementsZ_identity_classZ_identity_key_propstupler&)rmappingssession_transactionisstatesr#r$r(cached_connectionsstatestable super_mapperrecordsZ identity_clsZidentity_propsrr)rrrr _bulk_insert#sH      r<c sj}t|}jjr*jjhfdd|rd|rTfdd|D}qldd|D}nt|}|jjr|t d| |xX|j D]J\}} |sqtd|fdd|Dd d } t|d|||| d d qWdS) NcstfddjDS)Nc3s,|]$\}}|jks|kr||fVqdS)N)committed_state)rkv) search_keysrrrr sz6_bulk_update.._changed_dict..)rr/)rr)r@)rr _changed_dict~s z#_bulk_update.._changed_dictcsg|]}|qSrr)rr)rArrrrsz _bulk_update..cSsg|] }|jqSr)r)rrrrrrszJconnection_callable / per-instance sharding not supported in bulk_update()c3s.|]&}d|jr |jjndfVqdS)N)_version_id_propr&)rr!)rrrrr s z_bulk_update..T)r"F)r%)r(r)Z_primary_key_propkeysrBr&unionr-r*r+r,rr.r/r0_collect_update_commands_emit_update_statements) rr4r5r6Zupdate_changed_onlyr(r7r9r:r;r)rArrr@r _bulk_updatess@    rFFcCs|s2|js2x"t|D]}t||g|ddqWdSg}g}t|}xRt|||D]B\}}} } } } } | sj| r|||| | | fqP|||| | fqPWx\|jD]N\}} || jkrqt ||}t |||}t |||| ||t |||| ||qWt ||tdd|Ddd|DdS)a;Issue ``INSERT`` and/or ``UPDATE`` statements for a list of objects. This is called within the context of a UOWTransaction during a flush operation, given a list of states to be flushed. The base mapper in an inheritance hierarchy handles the inserts/ updates for all descendant mappers. T)singleNcss$|]\}}}}||||dfVqdS)FNr)rrrrrrrrr szsave_obj..css&|]\}}}}}||||dfVqdS)TNr)rrrrrupdate_version_idrrrr s )Zbatch _sort_statessave_objr)_organize_states_for_saveappendr.r/ _pks_by_tabler1rDrEr2 _finalize_insert_update_commandsr)r(r8uowtransactionrGrstates_to_updatestates_to_insertr7rrr has_identity row_switchrHr9insertupdaterrrrJsR     rJcsvt|}tt|||}xX|jD]J\jkr8q$fdd|D}t||||}t||||q$WdS)z\Issue UPDATE statements on behalf of a relationship() which specifies post_update. c 3sH|]@\}}}}|jkr||||jdk r:||jndfVqdS)N)rMversion_id_col#_get_committed_state_attr_by_column)rrrZ sub_mapperr)rr9rrr s zpost_update..N)r)r- _organize_states_for_post_updater.r/rM_collect_post_update_commands_emit_post_update_statements)r(r8rOpost_update_colsr7rPrUr)rr9r post_updates"  r\c Cst|}tt|||}|j}x\tt|D]H}||}||jkrJq0n|jrX|jrXq0t ||||}t ||||||q0Wx&|D]\} } }} } |j || | qWdS)zIssue ``DELETE`` statements for a list of objects. This is called within the context of a UOWTransaction during a flush operation. N) r)r-_organize_states_for_deleter.reversedkeysrMZinheritsZpassive_deletes_collect_delete_commands_emit_delete_statementsdispatchZ after_delete) r(r8rOr7states_to_deleteZtable_to_mapperr9rdeleterrrrHrrr delete_obj;s,    rec csPxHt|||D]6\}}}}t|j}|jp6||}d} } |sV|j|||n|j||||jrz|||||s||jj kr|jj |} t | } | | s| | stdt||t| f|d|t|t| || | } |s| r4|jdk r4|| r| n|| r*| jn||j} |||||| | fVqWdS)aTMake an initial pass across a set of states for INSERT or UPDATE. This includes splitting out into distinct lists for each, calling before_insert/before_update, obtaining key information for each state including its dictionary, mapper, the connection to use for the execution per state, and the identity flag. NzJNew instance %s with identity key %s conflicts with persistent instance %szPdetected row switch for identity %s. will update %s, remove %s from transaction)_connections_for_statesboolr&_identity_key_from_staterbZ before_insertZ before_updateZ_validate_polymorphic_identityr* identity_maprinstance_stateZwas_already_deleted is_deletedorm_exc FlushErrorr Z _log_debugZremove_state_actionsrVrWr) r(r8rOrrrrrRZ instance_keyrSrHinstanceZexistingrrrrKisL          rKcCs t|||S)zMake an initial pass across a set of states for UPDATE corresponding to post_update. This includes obtaining key information for each state including its dictionary, mapper, the connection to use for the execution per state. )rf)r(r8rOrrrrXs rXccsbx\t|||D]L\}}}}|j||||jdk rF||||j}nd}|||||fVqWdS)zMake an initial pass across a set of states for DELETE. This includes calling out before_delete and obtaining key information for each state including its dictionary, mapper, the connection to use for the execution per state. N)rfrbZ before_deleterVrW)r(r8rOrrrrrHrrrr]s r]c csx|D]\}}}}||jkr"qi} i} |j|} |j|} x~t| |D]l} || }| | }|dkrz|| krz|szqNqN|st|dst|tjrt|dr| n|| |<qN|| |j <qNW|sx0|j | |  dd| DD] }d| |<qW|r|r0|j || }|jjr*|j|| }nd}nd}}|jdk rt|jdk rt|j|j|krt|d| |jj <||| ||| ||fVqWdS)zSIdentify sets of values to use in INSERT statements for a list of states. N__clause_element__cSsg|] }|jqSr)r&)rcrrrrsz,_collect_insert_commands..TF)rM_propkey_to_colZ_insert_cols_evaluating_noneset intersectionhasattr isinstancer ClauseElementror&Z_insert_cols_as_none differenceZ_pk_keys_by_tableissubsetr(eager_defaultsZ_server_default_colsversion_id_generatorrV_cols_by_table)r9rQr"r#r$rrrrrrpropkey_to_colZ eval_nonepropkeyvaluecolZcolkeyrrrrrr1sX              r1c #sxxp|D]f\}}}}||jkr$q|j|}i} |j||rttfddt|j|D} d} ni} xt|jD]n} | } | }t| dst | t j rt| dr| n| | |<q|j | j| |j| dk r| | |j<qW|jjr|j|| } nd} |dk r|j|j|kr|s| s| sx:|jD]*}|j |jj|tj}|jrVPqVWq|j}| o| }|| |j<|s|j| kr|jdk r||}|| |j<n|jdkr|r|| |j<n| s| sqd}d}|r.TroNFc3s"|]}|j|fVqdS)N)_labelget)rr})r|rrrr sZ pk_cascadedrzCCan't update table %s using NULL for primary key value on column %s)*rMrqrrrrsrwZ_pk_attr_keys_by_tabler=rtrur rvromanagerimplZis_equalr&r(ryZ_server_onupdate_default_colsrxrVr{_columntopropertyvalues get_historyrPASSIVE_NO_INITIALIZEaddedrrz PASSIVE_OFFZdeletedpopZ unchangedrlrmrU_table_to_equatedr populatepassive_updates)rOr9rPr"rrrrHpksrrrr}r~rprophistoryZ no_paramsvalrZexpect_pk_cascadedZ pk_paramsm equated_pairsr)r|rrrD7s                               rDccs6x.|D]$\}}}}} |j|} i} d} x|j|D]|} | | kr^|j||| tjd| | j<q6| |ksp| jdk r6|j| }|j|j j ||tj }|j r6|j d}|| | j <d} q6W| r| dk r|j|j|kr|j} | | | j<t|j r| j | kr|jdk r|| }|| | j <||||| fVqWdS)zrIdentify sets of values to use in UPDATE statements for a list of states within a post_update operation. F)ZpassiveNrT)rMr{Z_get_state_attr_by_columnrrrZonupdaterrr&rrrrrVrgrz)r(rOr9rPr[rrrrrHrrZhasdatarrrr~rrrrrYs8            rYc csx|D]\}}}}}||jkr qi} xD|j|D]6} |||| | | j<} | dkr0td|| fq0W|dk r|j|j|kr|| |jj<| |fVqWdS)zSIdentify values to use in DELETE statements for a list of states to be deleted.NzHCan't delete from table %s using NULL for primary key value on column %s)rMrWr&rlrmrVr{) r(rOr9rcrrrrrHrrr~rrrr`(s   r`Tc sjdk ojjkfdd}|df|}xRt|ddD]>\\} } } } } }d}t|}|}d}| s|}d }n8|r| sjjr|}d }njdk r|j}d }|s| jj n| jj }|o| jj }| o }| rTxb|D]Z\}}}} }} } | | ||}|r@t|||||jjd|d ||j7}|}qWn|s|}x|D]V\}}}} }} } ||  ||}|rt|||||jjd|d ||j7}qdWnd d |D}|p|ot|d k}||  ||}||j7}xD|D]<\}}}} }} } |rt|||||jjd|d qW|rv|t|krtd jt||fqLrLtd|jjqLWdS)z`Emit UPDATE statements corresponding to value lists collected by _collect_update_commands().Ncspt}x0jD]"}|j|tj|j|jdkqWrb|jjtjjjjjdk |}|S)N)type_) r and_rMclausesrL bindparamrtyperVrU)clauserstmt)rneeds_version_idr9rr update_stmt`s z,_emit_update_statements..update_stmtrUcSs*|dt|dt|d|d|dfS)Nr )rrrg)recrrr{s   z)_emit_update_statements..rFTcSsg|] }|dqS)r r)rrrrrrsz+_emit_update_statements..rzMUPDATE statement on table '%s' expected to update %d row(s); %d were matched.zMDialect %s does not support updated rowcount - versioning cannot be verified.)rVr{_memorr-r#r(rydialectsupports_sane_rowcount supports_sane_rowcount_returningsupports_sane_multi_rowcountexecuter _postfetchcontextcompiled_parametersrowcountlenrlStaleDataError descriptionrwarndialect_description)r(rOr7rr9rUr%r cached_stmtrZ paramkeyshasvaluerrr;rows statementr#assert_singlerowassert_multirowallow_multirowrrrrrpcheck_rowcount multiparamsr)rrr9rrEOs               rEc Cs|d|f|j}xt|ddD]\\}} } } } } |}|rZ| sR|jrR|jjs| r| st| } dd| D}||||}|rxTt| |j j D]B\\}}}}}}} } }|rt ||||||||d qt |||qWq$| s|jr| }n|jdk r| |j}x| D]\}}}}}}} } |r<||||}n||||}|j j}|dk rxXt||j|D]D\}}|j|}|dk rp||ks||jdkrp|||j<qpW|r|rt |||||||j j d|d n t |||qWq$WdS) z`Emit INSERT statements corresponding to value lists collected by _collect_insert_commands().rTcSs*|dt|dt|d|d|dfS)Nrr rrr)rrrg)rrrrr#s   z)_emit_insert_statements..cSsg|] }|dqS)r r)rrrrrr:sz+_emit_insert_statements..FNr)rrTrryrZimplicit_returningr-rziprrr_postfetch_bulk_saver#rVrZinserted_primary_keyrMrrr&)r(rOr7rr9rTr%rrZpkeysrrrr;rrrprrr mapper_recrrZlast_inserted_paramsresult primary_keypkrrrrrr2s~   &          r2c sjdk ojjkfdd}|df|}xtt|ddD]`\}} d} t| } |d} jdkr|| jjn| jj} | o| jj}  p| }|s| }x| D]D\}}}} }||  ||}t ||||||j j d| |j 7} qWnvdd | D}| p| ot|d k}||  ||}| |j 7} x4| D],\}}}} }t ||||||j j dq8W|r| t| krtd jt| | fqLrLtd |jjqLWdS) zeEmit UPDATE statements corresponding to value lists collected by _collect_post_update_commands().Ncst}x0jD]"}|j|tj|j|jdkqWrb|jjtjjjjjdk |}jdk r| j}|S)N)r) r rrMrrLrrrrVrUr#)rrr)rrr9rrrs   z1_emit_post_update_statements..update_stmtr\cSs|dt|dfS)Nr)rr)rrrrrz._emit_post_update_statements..rcSsg|]\}}}}}|qSrr)rrrrrrrrrrsz0_emit_post_update_statements..rzMUPDATE statement on table '%s' expected to update %d row(s); %d were matched.zMDialect %s does not support updated rowcount - versioning cannot be verified.)rVr{rrr-rrrrr_postfetch_post_updaterrrrrlrrrrr)r(rOr7rr9rUrrr&r;rrrrrrrrrrrprr)rrr9rrZsh   rZcs`jdk ojjkfdd}|df|}xt|ddD] \}} dd| D} ||}t| } d } d } r|jjs|jjrd } xF| D]}|||}| |j 7} qWqt j d |jj d d||| n||| }sd} |j } |j rL| d krL| | krL|jjs$t| dkrL| rBt dj| | fqLtdj| | fqLWdS)z`Emit DELETE statements corresponding to value lists collected by _collect_delete_commands().Ncslt}x0jD]"}|j|tj|j|jdkqWrb|jjtjjjjjdk |S)N)r) r rrMrrLrr&rrVrd)rr)rneed_version_idr9rr delete_stmtsz,_emit_delete_statements..delete_stmtrdcSs|dS)Nrr)rrrrr"rz)_emit_delete_statements..cSsg|] \}}|qSrr)rrrrrrr#sz+_emit_delete_statements..FrzMDialect %s does not support deleted rowcount - versioning cannot be verified. ) stacklevelTrzDELETE statement on table '%s' expected to delete %d row(s); %d were matched. Please set confirm_deleted_rows=False within the mapper configuration to prevent this warning.)rVr{rrrrrrrrrrrZconfirm_deleted_rowsrrlr)r(rOr7rr9rdrrrZrecsZ del_objectsZexpectedZ rows_matchedZ only_warnrrpr)rrr9rrasL      rac s"x|D]\}}}}|jrJfdd|jD}|rJj|g}|jrh|j|j|j dk r|j dkr|j j j kr||j j g|r|_ tj|j|j |d|s|j||n|j|||j dkr|j dk r||j j dkrtdqWdS)zzfinalize state on states that have been inserted or updated, including calling after_insert/after_update events. csBg|]:}|jr |jr8|jjks8|js|js|jjkr|jqSr)Zexpire_on_flushZdeferredr&r)rr')rrrrms z4_finalize_insert_update_commands..NF)Z refresh_stateZonly_load_propsz2Instance does not contain a non-NULL version value)Z_readonly_propsZunmodified_intersection_expire_attributesrryextendZ_unloaded_non_objectrsZ&_server_default_plus_onupdate_propkeysrVrzrBr&ZunloadedrhrZ load_on_identr*queryrbZ after_insertZ after_updaterlrm) r(rOr8rrrrRreadonlyZ toload_nowr)rrrNcs>         rNc s||rdS|jjj}|jjj}jdk rLjj|krLt|jg}tj j j } | rbg} xL|D]D} | j |krh| j krh|| j |j | j <| rh| j | j qhW| r| rʈj j ||| |r||jfdd|DdS)Ncs"g|]}|jkrj|jqSr)rr&)rrp)rrrrsz*_postfetch_post_update..)rkrcompiledprefetch postfetchrVr{r-rg class_managerrb refresh_flushr&rrLrr) rrOr9rrrr prefetch_colspostfetch_colsrload_evt_attrsrpr)rrrs.       rc  s|jjj} |jjj} |jjjjdk rHjj|krHt| jg} tj j j } | r^g} r|jj } | dk rxJD]B}|j r|jjrqxj|}|rx| |||j<| rx| |jqxWxL| D]D}|j|kr|jkr||j|j|j<| r| j|jqW| r*| r*j j ||| |rN|rN| fdd|D| rp||jfdd| Dx0j|D]"\}}t||||||jq|WdS)zExpire attributes in need of newly persisted database state, after an INSERT or UPDATE statement has proceeded for that state.Ncsg|]}|jr|kr|qSr)r)rr)returning_colsrrrsz_postfetch..cs"g|]}|jkrj|jqSr)rr&)rrp)rrrrs)rrrrZ returningrVr{r-rgrrbrZreturned_defaultsrZisinsertrrr&rLrrrrr rr)rrOr9rrrrrZisupdaterrrrrowrrrprrr)rrrrs\              rcCs*x$|j|D]\}}t|||q WdS)N)rr Zbulk_populate_inherit_keys)rrr9rrrrrr2srccsb|jjr|jj}n|j|}d}x:t|D].}|rB|||}|jj}||j||fVq,WdS)zReturn an iterator of (state, state.dict, mapper, connection). The states are sorted according to _sort_states, then paired with the connection they should be using for the given unit of work transaction. N) r*r+Z transactionrrIobjrrr)r(rOr8r+rrrrrrrf7s   rfcstfddS)Ncs|jjdS)N)Zcompiled_cache)Zexecution_optionsZ_compiled_cache)r)r(rrrTsz)_cached_connection_dict..)rZ PopulateDict)r(r)r(rr)Qsr)c Cst|}tdd|D}||yt|ddd}Wn0tk rh}ztd|Wdd}~XYnXt|tdd|S)Ncss|]}|jdk r|VqdS)N)r&)rsrrrr \sz_sort_states..cSs |jdS)Nr)r&)qrrrr_rz_sort_states..)r&z^Could not sort objects by primary key; primary key values must be sortable in Python (was: %s)Z insert_order)rrdifference_updatesorted TypeErrorsa_excInvalidRequestErroroperator attrgetter)r8ZpendingZ persistentZpersistent_sortederrrrrrIZs rIc@sreZdZdZddZddZeddZedd Z d d Z d d Z ddZ e dddZddZddZdS)BulkUDz5Handle bulk update and deletes via a :class:`.Query`.cCs$|d|_|j|_|dS)NF)Zenable_eagerloadsrZ _bind_mapperr_validate_query_state)selfrrrr__init__ns  zBulkUD.__init__c Csx~dddtjfdddtjfdddtjfdd dtjfd d dtjfd d dtjffD].\}}}}|t|j||sNtd|fqNWdS)NZ_limitzlimit()Z_offsetzoffset()Z _order_byz order_by()FZ _group_byz group_by()Z _distinctz distinct()Z _from_objz2join(), outerjoin(), select_from(), or from_self()rzCCan't call Query.update() or Query.delete() when %s has been called)ris_eqgetattrrrr)rattrZmethnameZnotsetoprrrrss     zBulkUD._validate_query_statecCs|jjS)N)rr*)rrrrr*szBulkUD.sessionc GsPy ||}Wn6tk rBtddtdd|DYn X||SdS)Nz3Valid strategies for session synchronization are %sz, css|]}t|VqdS)N)repr)rxrrrr sz"BulkUD._factory..)KeyErrorrZ ArgumentErrorjoinr)clslookupsynchronize_sessionargklassrrr_factorys "zBulkUD._factorycCs4||||||dS)N)_do_before_compile_do_pre_do_pre_synchronize_do_exec_do_post_synchronize_do_post)rrrrexec_s z BulkUD.exec_cCs |j||j|_|jj|_dS)N)rZ _execute_crudrrr)rrrrr _execute_stmtszBulkUD._execute_stmtcCs tdS)N)r,)rrrrrszBulkUD._do_before_compilezsqlalchemy.orm.querycCs|j}|||_t|jd|jrt}x6|jD],}t||jsN|Pq2|t |j q2Wt |dkrzt dq||_n|djj|_|j}|jr|dS)NrrzLThis operation requires only one Table or entity be specified as the target.)rZ QueryContextrruZ _entitiesZ _ColumnEntityrrclearrUrcolumnrrrr primary_tableZ_only_entity_zerorZ local_tabler*Z _autoflush)rZquerylibrZtablesZentr*rrrrs$      zBulkUD._do_precCsdS)Nr)rrrrrszBulkUD._do_pre_synchronizecCsdS)Nr)rrrrrszBulkUD._do_post_synchronizeN)__name__ __module__ __qualname____doc__rrpropertyr* classmethodrrrrrZ dependenciesrrrrrrrrks  #rc@s eZdZdZddZddZdS) BulkEvaluatezDBulkUD which does the 'evaluate' method of session state resolution.cCsdS)Nr)revaluator_compilerrrr_additional_evaluatorssz#BulkEvaluate._additional_evaluatorsc s|j}|jy8t}|jdk r4||jndd||Wn2tjk rz}zt d|Wdd}~XYnXfdd|j j D|_dS)NcSsdS)NTr)rrrreval_conditionsz8BulkEvaluate._do_pre_synchronize..eval_conditionztCould not evaluate current criteria in Python: "%s". Specify 'fetch' or False for the synchronize_session parameter.cs,g|]$\\}}}}t|r|r|qSr) issubclass)rrrZidentity_tokenr)r  target_clsrrrs z4BulkEvaluate._do_pre_synchronize..)r _mapper_zeroZclass_rZEvaluatorCompiler whereclauseprocessrZUnevaluatableErrorrrr*rir/matched_objects)rrrrr)r r rrs    z BulkEvaluate._do_pre_synchronizeN)rrrrrrrrrrrsrc@seZdZdZddZdS) BulkFetchzABulkUD which does the 'fetch' method of session state resolution.cCsB|j}|j}|}|j|jj}|j||j|j d |_ dS)N)rr) rr*Z_compile_contextrZwith_only_columnsrrrrZ_paramsZfetchall matched_rows)rrr*rZ select_stmtrrrrs zBulkFetch._do_pre_synchronizeN)rrrrrrrrrrsrcs\eZdZdZfddZeddZddZedd Z ed d Z d d Z ddZ Z S) BulkUpdatezBulkUD which handles UPDATEs.cs tt||||_||_dS)N)superrrr update_kwargs)rrrr) __class__rrr szBulkUpdate.__init__cCsttttd||||S)N)evaluatefetchF)rrBulkUpdateEvaluateBulkUpdateFetchr)rrrrrrrrfactoryszBulkUpdate.factorycCs<|jjjr8x,|jjjD]}||j|}|dk r||_qWdS)N)rrbZbefore_compile_update)rfn new_queryrrrrs   zBulkUpdate._do_before_compilecCsg}xt|jdr|jn|jD]t\}}|jrt|tjrZt|j|}|| |qt|t j rx|| |q| ||fq"| ||fq"W|S)Nr/) rtrr/rrurZ string_typesr rZ_bulk_update_tuplesrQueryableAttributerL)rrr>r?Zdescrrr_resolved_values$s   zBulkUpdate._resolved_valuesc Csg}x|jD]\}}t|tjr4||j|fq nt|drF|}|jrt|t j ry|jj |}Wnt j k r~YqX||j|fq td|q W|S)NrozInvalid expression type: %r)rrurrrLr&rtrorrZ ColumnElementrrlZUnmappedColumnErrorrr)rrr>r?rrrr"_resolved_values_keys_as_propnames8s   z-BulkUpdate._resolved_values_keys_as_propnamescCsD|j}|jddst|}tj|j|jj|f|j}| |dS)NZpreserve_parameter_orderF) rrrrr rUrrr r)rrrrrrrOszBulkUpdate._do_execcCs|jj}|j|dS)N)rr*rbZafter_bulk_update)rr*rrrr^szBulkUpdate._do_post)rrrrrrrrrrrrr __classcell__rr)rrrs    rcsDeZdZdZfddZeddZddZdd Zd d Z Z S) BulkDeletezBulkUD which handles DELETEs.cstt||dS)N)rr!r)rr)rrrrfszBulkDelete.__init__cCsttttd||S)N)rrF)rrBulkDeleteEvaluateBulkDeleteFetchr!)rrrrrrris zBulkDelete.factorycCs<|jjjr8x,|jjjD]}||j|}|dk r||_qWdS)N)rrbZbefore_compile_delete)rrrrrrrus   zBulkDelete._do_before_compilecCs t|j|jj}||dS)N)r rdrrr r)rrrrrr|szBulkDelete._do_execcCs|jj}|j|dS)N)rr*rbZafter_bulk_delete)rr*rrrrszBulkDelete._do_post) rrrrrrrrrrr rr)rrr!cs   r!c@s eZdZdZddZddZdS)rzSBulkUD which handles UPDATEs using the "evaluate" method of session resolution.cCs8i|_|j}x&|D]\}}|t||j|<qWdS)N)value_evaluatorsrrrZ_literal_as_binds)rrrr&r~rrrrs z)BulkUpdateEvaluate._additional_evaluatorsc Cs|jj}t}t|j}x|jD]}t|t |}}|j |}x|D]}|j||||<qPW|j j |d|||t|||t||||q$W||dS)N)rr*rrr-r$r_rrrjZ instance_dictZ unmodifiedrsrrbZrefreshZ_commitrrwadd_register_altered) rr*r8Zevaluated_keysrrrZ to_evaluater&rrrrs   z'BulkUpdateEvaluate._do_post_synchronizeN)rrrrrrrrrrrsrc@seZdZdZddZdS)r"zSBulkUD which handles DELETEs using the "evaluate" method of session resolution.cCs|jjdd|jDdS)NcSsg|]}t|qSr)rrj)rrrrrrsz;BulkDeleteEvaluate._do_post_synchronize..)rr*_remove_newly_deletedr)rrrrrsz'BulkDeleteEvaluate._do_post_synchronizeN)rrrrrrrrrr"sr"c@seZdZdZddZdS)rzPBulkUD which handles UPDATEs using the "fetch" method of session resolution.cs|jj|jtfddfdd|jDD}|j}tdd|D}x(|D] }||j}|rV||qVW |dS)Ncs&g|]}|jkrtj|qSr)rirrj)r identity_key)r*rrrsz8BulkUpdateFetch._do_post_synchronize..csg|]}t|qSr)identity_key_from_primary_keyr-)rr) target_mapperrrrscss|]\}}|VqdS)Nr)rr>r?rrrr sz7BulkUpdateFetch._do_post_synchronize..) rr*r rrrrrsrZ _expire_stater&)rr8rZattribrZ to_expirer)r*r*rrs     z$BulkUpdateFetch._do_post_synchronizeN)rrrrrrrrrrsrc@seZdZdZddZdS)r#zPBulkUD which handles DELETEs using the "fetch" method of session resolution.cCsV|jj}|j}x>|jD]4}|t|}||jkr|t |j|gqWdS)N) rr*r rr)r-rir'rrj)rr*r*rr(rrrrs    z$BulkDeleteFetch._do_post_synchronizeN)rrrrrrrrrr#sr#)F)FFF)F)T)T)6r itertoolsrrrrrrrlrr baser r rr rrZsql.baserr<rFrJr\rerKrXr]r1rDrYr`rEr2rZrarNrrrrfr)rIobjectrrrrr!rr"rr#rrrrsf              PE V-.Q  U 98. B {s^F)` e(\#(