gdZddlmZddlmZddlmZddlmZddlZddlm Z dd lm Z dd lm Z dd lm Z dd lmZd d lm Zd dlmZd dlmZd dlmZd dlmZd dlmZd dlmZd dlmZd0dZdZdZdZdZ dZ!ddddddZ"ddddd Z#d!Z$d"Z%d#dd#d$d%Z&d#ddd&d'Z'd(Z(d)Z)d*Z*d+Z+d,Z,d-Z-d.Z.d/Z/y)1zprivate module containing functions used to emit INSERT, UPDATE and DELETE statements on behalf of a :class:`_orm.Mapper` and its descending mappers. The functions here are called only by the unit of work functions in unitofwork.py. ) annotations)chain)groupby) zip_longestN) attributes)exc)loading)sync) state_str)future)sql)util)cursor) operators)BooleanClauseList)LABEL_STYLE_TABLENAME_PLUS_COLFc |s.|js"t||D]}t||g|dyg}g}t|||D]:\}}}} } } } | s| r|j |||| | f&|j |||| f<|j j D]K\} }| |jvrt| |}t|| |}t|||| |t|||| |Mt||td|Dd|Dy)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)singleNc34K|]\}}}}||||dfyw)FN).0state state_dictmapper connections K/opt/hc_python/lib64/python3.12/site-packages/sqlalchemy/orm/persistence.py zsave_obj..is, ?O;UJ  FJ>?Osc36K|]\}}}}}||||dfyw)TNr)rrrrrupdate_version_ids rrzsave_obj..ms9 & %  FJ=&s)batch _sort_statessave_obj_organize_states_for_saveappend_sorted_tablesitems _pks_by_table_collect_insert_commands_collect_update_commands_emit_update_statements_emit_insert_statements _finalize_insert_update_commandsr) base_mapperstatesuowtransactionrrstates_to_updatestates_to_insertdict_rr has_identity row_switchr!tableinsertupdates rr$r$(s] +++!+v6E [5'>$ G7 #; G    :  # #vz3DE   # #UE6:$F G H%3399; v ,, , )%1AB) E#3               #<2%  ?O  &   ctt|||}|jjD]>\jvrfd|D}t ||||}t |||@y)z\Issue UPDATE statements on behalf of a relationship() which specifies post_update. c 3K|]G\}}}}|jvr2||||jj||jndfIywN)r)version_id_col#_get_committed_state_attr_by_column)rrr sub_mapperrrr7s rrzpost_update..st >N9z:z 000 ,,8>>z6+@+@ >NsA AN)list _organize_states_for_post_updater'r(r)_collect_post_update_commands_emit_post_update_statements)r/r0r1post_update_colsr2r9rr7s @@r post_updaterF{s (fnM%3399; v ,, ,  >N $/ 8H  %       5r?dict) r/r0r1rr4rrr5 instance_keyr6r!instanceexistings rr%r%s-D^V-(ufjEII yyJF$C$CE$J )-- & OO ) )&*e D OO ) )&*e D  0 0  1 1&% G 6 6 C CC%--::<HH!00:H!55h?%00:II%U+\9X;NP  **&%!%(!(+ #77A!)J JF,A,A,M & J J( e#- 5%%!          s-sG Gct|||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. )rV)r/r0r1s rrBrB#s #; GGr:c#Kt|||D]Y\}}}}|jj||||j|j |||j}nd}|||||f[yw)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)rVrO before_deleter>r?)r/r0r1rr4rrr!s rrHrH/s-D^V-(ufj %%fj%@  , & J Juf33! !% eVZ1BCC-sA+A-r)bulkreturn_defaults render_nullsinclude_bulk_keysc #K|D]<\}}}||jvri} i} |j|} |j|} t| j D]n} | }| | }||| vr|s|sHt |dst |tjr"t |dr|jn|| |<`|| |j<p|sO|j|j| j| Dcgc]}|jc}D]}d| |< |r|rf|j|j| }|jj!|j"|r|j$|j| }nd}ndx}}|j&durO|j(C|j(|j*|vr(|j'd| |j(j<|rN|j,r&| j/|j0|j2|r| j5fd|D|| ||| ||f?ycc}ww)zSIdentify sets of values to use in INSERT statements for a list of states. N__clause_element__TFc3,K|] }||f ywr=rrkrs rrz+_collect_insert_commands..sL:KQq*Q-0:K)r)_propkey_to_col_insert_cols_evaluating_noneset intersectionhasattr isinstancer ClauseElementrqrX_insert_cols_as_none difference_pk_keys_by_tableissubsetr/_prefer_eager_defaultsdialect_server_default_col_keysversion_id_generatorr>_cols_by_table_set_polymorphic_identity setdefault_polymorphic_attr_keypolymorphic_identityr9)r7r3rlrmrnrorrrparams value_paramspropkey_to_col eval_nonepropkeyvaluecolccolkey has_all_pkshas_all_defaultsrs @rr*r*Fs2B-z6: ,, ,  //677> >*77 CGw'E )C}I!5l34eS%6%67u&:;,,.S! #(swwD"++E2F#L9LqQUUL9:; "&v ; !2259BB6JK!!88""E$*#B#B$(6"!$( -1 1 {  ' 'u 4%%1%%)>)>u)EE060K0K1F6((,, - //!!00&2M2M! L:KLL          Y2BL:sC5I 8I EI )rluse_orm_update_stmtroc #h K|D]\}}}} ||jvr|j|} | |j} ni} |j|} |rWt| j j |j |D cic]} | | j| }} d}ni}t| j |jD]} | }| | }t|dst|tjr"t|dr|jn|| |<U|j| jj!||j| dus|||j<|j"j$dur|j&|j)|}nd}| |j*|j,|vr|su|ss| sq|j.j1D]R}|j|jjj3|t4j6}|j8sRn4|j*}| xr| }| ||j:<|s|j|vr/|j<dur!|j=| }|||j<n&|j<dur|r| ||j<n|s| sd}d}|rt| j |j |D cic]!} | | j:j?| #c} t@jBj j1r\tEjFddjIfd| Ddd i| D]!}|j.|j} |j| jj3|t4jJ}|j8r{|jLrd ||f|j4vr;d}|j8d |j:<|jO|jdn?|jLd |j:<|| vrd}n|jPd |j:<|j: tSjTd |d||r|jWfd|D|s| r|jW||||| ||f|s|jX|D]*\}}t[j\|||||||j^,ycc} wcc} ww)atIdentify sets of values to use in UPDATE statements for a list of states. This function works intricately with the history system to determine exactly what values should be updated as well as how the row should be matched within an UPDATE statement. Includes some tricky scenarios where the primary key of an object might have been changed. NTrqFz,No primary key value supplied for column(s) z, c3TK|]}|jt|!ywr=)_labelstr)rr pk_paramss rrz+_collect_update_commands..3s'",/q9QXX3F3NCFCs((zY; per-row ORM Bulk UPDATE by Primary Key requires that records contain primary key valuesbupq)code pk_cascadedrzCan't update table , using NULL for primary key value on column c3,K|] }||f ywr=rrss rrz+_collect_update_commands..\sH6G1jm,6Gru)0r)_valuesrvrxryr~_pk_attr_keys_by_tablerXcommitted_staterzr{rr|rqmanagerimplis_equalr/eager_defaults!_server_onupdate_default_col_keysrr>r_columntopropertyvalues get_historyrPASSIVE_NO_INITIALIZEaddedrrgetrNONE_SETsa_excInvalidRequestErrorjoin PASSIVE_OFFdeletedpop unchangedorm_exc FlushErrorr9_table_to_equatedr populatepassive_updates)r1r7r2rlrrorrrr!pksrrrrrrrprophistory no_paramsvalrexpect_pk_cascadedm equated_pairsrrs @@rr+r+ss4     ,, , ""5)  *.66LL//6  #>2j)F99%@A B BGw'++Z-@@ B  $ F~.;;%%#7+$W-5"67:3,,< #5*>?002"!%MM'*//88u44W=  ',F377O-0!!00D8<)>u)EE< #44;;=D#mmDHH5::FFz:+K+KG}} >''C" 7<'7I!2F3:: v---U:112CD"%sww,,5) #4swwL  "  #>2??11%8  Gw'.. w0GG I }})))*:*:*<=00B ",/"9 9   I 2237;;--055AA:z'='===#OO)5#6)445.2*07 a0@ #**- 377D1180B #**-,.*/K,3,=,=a,@Icjj)SZZ(0!,,493@1:  MMH6GH H \ MM) $    %+$<$rWr)r/r1r7r2rErrrrr!rrhasdatarrrrrs rrCrC|s    ""5)((/Ccz%+%E%E:sJ4J4J&F&szz"((CLL,D//4--166BB:z'G'G==#MM!,E&+F377O"G0 !-))V-B-B5-II++%6szz"Ov-335@ 556GHC&)F377OVZ? ?K sA7F:AF$F=BFc#fK|D]\}}}}}||jvri} |j|D]A} |j||| x| | j<} | (tjd|d| |4|j |j |vr|| |j j<| |fyw)zSIdentify values to use in DELETE statements for a list of states to be deleted.NzCan't delete from table r)r)r?rXrrr>r) r/r1r7rQrrrrr!rrrs rrMrMs     ,, , ''.C:::s F377Oe }((16s</  )%%)>)>u)EE0AF6((,, -j  / s AB1AB1T) bookkeepingrenable_check_rowcountc@jduxrjjvd|ji}dfd } | | |} n|jdf| } t |dD]%\\} } } }}}d}t |}| }||j d}d}|s|jj}d }|rZ|sXjjd ur@jr4| jjr|jj}d }jr|jj}d }| jj }|xr| jj"}| xr }| r|D]z\}}}} }}}| j%|j'||| }|r5t)|||||j*j,d|d |j. ||j0z }|xr|}|n"|sq|xr|}|D]e\}}}} }}}| j%||| }|r5t)|||||j*j,d|d |j. ||j0z }gn|Dcgc]}|d  }}|xr|xs|xrt3|d k(}| j%||| }||j0z }|D][\}}}} }}}|st)|||||j*j,d|d |j*j4s |j.nd ]r>|t3|k7st7j8d j:t3||fzst=j>djj@z(ycc}w)z`Emit UPDATE statements corresponding to value lists collected by _collect_update_commands().Ncompiled_cachectjtj}jD]?}|j |t j|j|jk(Ar[|j jt jjjjjk(||j|}|Sjj|}|SN)type_) r_construct_rawrand_r)_append_inplacer bindparamrtyper>wherer9) existing_stmtclausesrstmtrneeds_version_idr7s r update_stmtz,_emit_update_statements..update_stmts#229>>B''.C  # #s}}SZZsxx@@ /   # #%%==))00 //44   $ &&w/D <<>''0D r:r9cR|dt|dt|d|d|dfSNr rxrWrecs rz)_emit_update_statements..2 F AK QL F F  r:r)_emit_update_table_emit_update_mapperFTexecution_optionsr rMUPDATE statement on table '%s' expected to update %d row(s); %d were matched.MDialect %s does not support updated rowcount - versioning cannot be verified.r=)!r>r_compiled_cache_memorrA _annotatermr)r/rimplicit_returningrupdate_returning_server_onupdate_default_cols!_version_id_has_server_side_valuesupports_sane_rowcountsupports_sane_multi_rowcountexecuter _postfetchcontextcompiled_parametersreturned_defaultsrowcountlen executemanyrStaleDataError descriptionrrbdialect_description) r/r1rr7r9rrrrr cached_stmtr paramkeyshasvaluerrrecordsrows statementrmassert_singlerowassert_multirowallow_executemanyrrrrrcheck_rowcountr multiparamsrs `` @rr,r,s} T) B  ! !V%:%:5%A A *;+F+FG.&!"56 "''5(9;G    HY*:Kw-  *!++*/+1I 1 1163G3G3NOI"O $""11T9((""331 1155e<I#O  3 3!11&2G2GHI"O%--DD  @""?? !0/H8H4H   &&$$\2&7' &" 55a8$++  "!6!K;K),%!6!K;K  $"**!6=N+A #""*!!&II99!<( // AJJ&D'*299#s1v 9!6"#D(BS-=-B &&{>O' "  $"""*!!&II99!<( ()yy'<'<!" 3 3%)& s7|#,,9((#g,=>  II3))//0 ] x:s< N)ruse_orm_insert_stmtrc |<|}tj} t|j} | xr |jxs|} n0d} |} |j d|f|j }d|ji} |r!tjj| |}n| }d} t|dD]\\} }}}}}|}||j||d}|r@|s>|j| j|r"|jr| jjs| s|r|st|}|Dcgc]}|d }}| j!|||}|st#||j$j&D]T\\}}}}}}}}}|r7t)||||||||d|j$j*s |j,nd Ht/|||Vt|}| s|jr|s}t1|d kDro| r| jj2s| s| jj4rd }n>| r7| rd }nd }t7j8d | jj:d|dd}nd}|=|s;|j| j|r|j<|j>|d|i}|j@|j=|j@|}n|r|j<|jBd|i}|r*|Dcgc]}|d }}| j!|||}|| |} n| jE|} |stG||j$j&|jH|jJxsdD]\\}}}}}}}}}} }!| tMjNd|zt#| |jP|D]?\}"}#|jR|#}$|jU|$jV1|"||$jV<A|rt)||||||||d|! t/|||h| rJ|D]-\}}}}} }}}|r$| j!|jY|||}n| j!|||}|jZ}%|%tMjNd|dt#|%|jP|D]C\}"}#|jR|#}$|#|vs|jU|$jV5|"||$jV<E|s|rOt)|||||||j$j&d|d|j$j*s |j,nd !t/|||0|| t]j^S| Sycc}wcc}w)z`Emit INSERT statements corresponding to value lists collected by _collect_insert_commands().NFr8rcR|dt|dt|d|d|dfSrrrs rrz)_emit_insert_statements..rr:)_emit_insert_table_emit_insert_mapperr rrTz+ with RETURNING and sort by parameter orderz with RETURNINGz primary_keysplice_verticallyrinserted_primary_key_rowsreturned_defaults_rowsrrr)rrrXrinserted_primary_key_cursornull_dml_result)&r/r1rr7r8rr rrexec_optreturning_is_required_anywaydeterministic_results_reqd return_resultr_rrrrrrr resultrrr mapper_recconnrlast_inserted_paramsdo_executemanydtrrpkrrrs& rr-r-s&) ??(,,?,J,J'K$ ( =#<<& # (-$%0"!''5(95<<H $k&A&AB OO66 ' %M    @Q+/?  *!++*/+1I $&=="**E!33%-->>1 7mG-45Wc3q6WK5'';:K(F&.."D"DE  ""$#(("&*!!&"0(!(.~~'A'A!' 8 8%)"-ZUK'F27mG+((c'lQ>N/"**__2"**GG%)N11J. 44*%--AABC&&(T)JL&+N!&"*(#::"**E!: 9 944U;!0;!I $$0%55)),76  5I55&&@K 189#s1v 9#++{>O,'2$,(. (5(G(G(O %::8855;  !&"& (',,,)07#*"4"4!8 ;E !E#(+0"007(GB$.#?#?#DD)~~dhh7?79 488 4 (!& * . % % * & 4 , % 1 1ZOY\877  $#!+!3!3%,,\:".?"4" ",!3!3%".?"4" #)"="=K"*%00 8B D$'#V%9%9%%@$C *;;C@</)~~dhh7?35Jtxx0$# & * . % % * & & B B1 E , %,2>>+E+E%+$<$<)-"1ZOiy d&  **, , 'S6~:s  U % U%c d|ji}jduxrjjvfd}|jdf|}jr|j j}t |dD]\}} d} t| } |d} | jj} | xr| jj}  xs| }|s[| }| D]S\}}}} }| j|||}t||||||jjd| |jz } Un| Dcgc] \}}}}}| }}}}}}| xs| xrt!|dk(}| j|||}| |jz } | D]0\}}}} }t||||||jjd2|r>| t!| k7sJt#j$d j&t!| | fzs|t)j*d jj,zycc}}}}}w) zeEmit UPDATE statements corresponding to value lists collected by _collect_post_update_commands().rNctjtj}jD]?}|j |t j|j|jk(Ar[|j jt jjjjjk(jj|}|Sr) rrrrr)rrrrrr>r9r)rrrrrr7s rrz1_emit_post_update_statements..update_stmts#229>>B''.C  # #s}}SZZsxx@@ /   # #%%==))00 //44 ||~##G, r:rFc(|dt|dfS)Nr)rxrs rrz._emit_post_update_statements..3sSVSQ[)r:rrrrr)rr>rrrrmrrArrrr_postfetch_post_updaterrrrrrrrrbr)r/r1rr7r9rrrrXrrrrrrr rrr(rrr)r rs `` @rrDrDs *;+F+FG T) B  ! !V%:%:5%A A *!!=%"8+FI //--f.C.CD  ) Ww-V %--DD  @""?? !10CO -NELAz:z6&&v9J''"II11!4 "FM$DKCJ?E:z4CJ  - :S%5%: "";:K#A AJJ DELAz:z6&"II11!4FM s7|#,,9((#g,=>  II3))//0 IDsH8cjduxrjjvfd}|jdf|}t|dD]\}}|D cgc]\} }|  } } }d|ji} t | } d} d}rj js|j jr-d} | D]%} |j|| | }| |jz } 'netjd |j jz|j|| | n$j|| | }sd }|j} |js| dkDs | | k7s|j jst | d k(s:|r'tjd j| | fzct!j"d j| | fzycc}} w)z`Emit DELETE statements corresponding to value lists collected by _collect_delete_commands().Nctjtj}jD]?}|j |t j|j|jk(Ar[|j jt jjjjjk(jj|Sr) rrrrr)rrrrXrr>rSr)rrrneed_version_idr7s r delete_stmtz,_emit_delete_statements..delete_stmts#229>>B''.C  # #s}}SWWCHH== /   # #%%==))--V5J5J5O5O ||~##G,,r:rSc |dS)Nrrrs rrz)_emit_delete_statements..sAr:rFrrzMDialect %s does not support deleted rowcount - versioning cannot be verified.TrzDELETE 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.)r>rrrrrrrrrrrrbrconfirm_deleted_rowsrrr)r/r1rr7rSr6rrrecsr del_objectsrexpected rows_matched only_warnrr5s `` @rrNrN|s T) B  ! !V%:%:5%A A -$!!8U"3[AI#F,>? D8<="4&*v =-{/J/JK{#   &&CC!!88 *F"**!6=N+A!AJJ.L *  7 ((<<= ""{>O#"";:K#A# ::L  , ,r!L(""??{#q(  =(((LA B,,=(((LA By@=s# G!c|D]c\}}}}}|jr|j|jDcgc]n}|jr$|jrH|j|j vs0|js0|js$|j|j vr |jpc}} | r|j |j | g} |jdur4| j|jj|j|jV|jdurH|jj|jvr&| j|jjg| rl|j!||_t#j$|j't(} t+j,|j.| |j|| |s|j0j3|||n|j0j5||||jdus(|j6||jjQt7j8dycc}w)zzfinalize state on states that have been inserted or updated, including calling after_insert/after_update events. TNF) refresh_stateonly_load_propsz2Instance does not contain a non-NULL version value)_readonly_propsunmodified_intersectionexpire_on_flushdeferredrXre_expire_attributesrextend_unloaded_non_objectry&_server_default_plus_onupdate_propkeysr>r_version_id_propunloadedrYrselectset_label_stylerr load_on_identr]rO after_insert after_updaterr) r/r1r0rrrrr5preadonly toload_nowrs rr.r.s$ @F;z6:|  ! !44$33 3))!"quu /B-- ! EE3EE3 H((X>    % % -   **77AA   ! ! -++u4&&**enn<!!6#:#:#>#>"?@ #<((HC@F sA3I+ c|jduxr|j|j|v}|j|sA|jjj }|jjj } n|rdx}} ny|rt||jgz}t|jjj} | rg} |D]t} | j|vs| |jvs!|| j||j| j<| sM j|j| jv| r) r'|jjj||| | rP|j|j | D cgc])} | |jvr|j| j+c} yycc} w)Nr)r>rrarcompiledprefetch postfetchrArW class_managerrO refresh_flushrXrr&rFre) rr1r7rr4r'rr prefetch_colspostfetch_colsrYload_evt_attrsrs rr2r2*s T) B  ! !V%:%:5%A A  $ $U +//88 00:: *,+  ]+v/D/D.EE --66DDEM  55F?qF$<$<<5;AEE]E&**1-11 2%%f&>&>q&A&E&EF  %%33 >>    JJ( 'A000((+//'   s.G c |jjj} |jjj} |jjj} |j 4|j |j |vrt| |j gz} t|jjj} | rg}| r| }|t|| D]s\}}|jr|jjr)|jj!|}|sG|||j"<| sYj%|j"u| D]{}|j"|vs||jvs!|j|j"}||j"||<|j&j)|d| skj%|}| r)r'|jjj||||r1|r/| j+|Dcgc]}|jr|| vr|c}| rO|j-|j.| Dcgc])}||jvr|j|j"+c}|j0|D]*\}}t3j4|||||||j6,ycc}wcc}w)zExpire attributes in need of newly persisted database state, after an INSERT or UPDATE statement has proceeded for that state.N)rrUrVrWeffective_returningr>rrArWrXrOrYrrisinsertrrrXr&rrrGrFrerr rr)rr1r7rr4r'rrisupdaterrZr[returning_colsrYr\row row_valuerrrpkeyrrs rrr\s NN++44M^^,,66N^^,,@@N )  ! !V%:%:5%A A]+v/D/D.EE --66DDEM ?"%c>": 3??v~~'>'> //33C8&/E$((O$&--dhh7#;  55F?qF$<$<<++A.22D!-E$K  ! ! % %dD 1%%d+%%33 >> L ( 'C??s.'@'     JJ( 'A000((+//'  #44U;=      " " <)  s K.K c`|j|D]\}}tj|||yr=)rr bulk_populate_inherit_keys)rr4r7rrs rrrs."44U;= ''q-@rs#!&,;Pf* Z(@VM ` HD6 b T Nb3@l#!ZgbA!H sl`FHV/ dg TA 44r: