U kf @s\dZddlmZddlZddlZddlmZddlmZddlmZddlm Z ddlm Z dd lm Z dd lm Z dd lm Z dd lmZdd lmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlm Z ddlm!Z!ddl"m#Z#ddl"m$Z$dd lm%Z%dd!lm&Z&dd"l'm(Z(erdd#l)m*Z*dd$l)m+Z+dd%lm,Z,dd&lm-Z-dd'lm.Z.dd(lm/Z/dd)lm0Z0dd*lm1Z1dd+lm2Z2e&3d,d-Z4d.d/d0d1d2Z5ed.e6eee6d3fe e6fZ7ed4e6e6e e6fZ8ed/e6d3e e6fZ9e e7Z:Gd5d6d6e Z;d7d8d9d:d;d6d<d=d>Zd7d8d9dNdOdPdQZ?dRdSZ@dTdUZAdVdWZBdXdYZCdZd[ZDd\d]ZEd^d_ZFd7d8d/d`dadbdcdddeZGdfdgZHedd7d.dAd;dCdhdidjZIed7d.dkd;dldhdmdjZIdd7d.d:dBd;dndodpdjZIedd7d.dAd;dCdhdqdrZJed7d.dkd;dldhdsdrZJdd7d.d:dBd;dndodtdrZJGdudvdvej/eZKd7d8d4dwdadCdxdydzZLd{d|ZMd7d8d9d}d~daddddZNddZOddZPddZQdS)ziFunctions used by compiler.py to determine the parameters rendered within INSERT and UPDATE statements. ) annotationsN)Any)Callable)cast)Dict)Iterable)List)MutableMapping) NamedTuple)Optional)overload)Sequence)Set)Tuple) TYPE_CHECKING)Union) coercions)dml)elements)roles)_DefaultDescriptionTuple)isinsert) ColumnClause)default_is_clause_element)default_is_sequence)Select) TableClause)exc)util)Literal)_BindNameForColProtocol) SQLCompiler)_DMLColumnElement)DMLState) ValuesBase) ColumnElement)KeyedColumnElement)_SQLExprDefault)ColumnREQUIREDa8 Placeholder for the value within a :class:`.BindParameter` which is required to be present when the statement is passed to :meth:`_engine.Connection.execute`. This symbol is typically used when a :func:`_expression.insert` or :func:`_expression.update` statement is compiled without parameter values present. zColumnElement[Any]ColumnClause[Any])creturncCst|tstd||S)Nz5Can't create DML statement against column expression ) isinstancerr CompileError)r-r1C/opt/hc_python/lib64/python3.8/site-packages/sqlalchemy/sql/crud.py_as_dml_columnJs  r3r)zKeyedColumnElement[Any]c@sBeZdZUded<ded<dZded<dZded<d Zd ed <d S) _CrudParams_CrudParamSequenceZ single_params$List[Sequence[_CrudParamElementStr]]Zall_multi_paramsFboolis_default_metavalue_onlyuse_insertmanyvaluesNzOptional[Sequence[Column[Any]]]use_sentinel_columns)__name__ __module__ __qualname____annotations__r8r9r:r1r1r1r2r4js   r4r#r&r%r7r)compilerstmt compile_statetoplevelkwr.c sg_g_g_g_|dd}|dk r8|ddd|ksHtdt||\}}|_|j rv|j rvt d|j rt||d||dd|| tggSjdkr|jrtfdd|jjDgSt|r|jr|j}|dk st|d } t| } fd d | Dnp|jrP|j} |j} | dk ss z$_get_crud_params..rcsh|] }|qSr1r1rLrJ_column_as_keyr1r2 sz#_get_crud_params..csh|] }|qSr1r1rNrOr1r2rQscsh|] }|qSr1r1rNrOr1r2rQscsi|]}|kr|tqSr1r+rN)rP spd_str_keyr1r2 sz$_get_crud_params..csi|]}|tqSr1rRrNrOr1r2rTsFc3s|]\}}|VqdSNr1)rLkvrOr1r2 Ksz#_get_crud_params..zUnconsumed column names: %s, css|]}d|fVqdS)z%sNr1rKr1r1r2rXQsSequence[_CrudParamElementStr]Callable[..., str]T)r8r9r:)0 postfetchinsert_prefetchupdate_prefetchimplicit_returninggetpopAssertionError_key_getters_for_crud_columnZ_get_bind_name_for_col _returning_return_defaultsrr0isdelete_setup_delete_return_defaultsr4Z column_keysZ_no_parameterstablecolumns_compile_state_isinsert_has_multi_parameters_multi_parameterslistitemsZ_ordered_valuesZ_dict_parameters!_get_stmt_parameter_tuples_paramsrisupdateZ is_multitable_get_update_multitable_params _select_names_scan_insert_from_select_cols _scan_colsset intersection differencejoin_extend_values_for_multiparamsrfor_executemanydialectZsupports_default_metavaluer3rGrHZdefault_metavalue_token)r?r@rArBrCrD_getattr_col_key_col_bind_namempZspdstmt_parameter_tuples parametersvalues check_columnsr9r:checkr8Zmulti_extended_valuesr1)rPr?rSr2_get_crud_paramsrsb(                       r.Fz Literal[True]z Optional[str]str)r?colvalueprocessrFnamerCr.cKsdSrUr1)r?rrrrFrrCr1r1r2rIs rI)r?rrrCr.cKsdSrUr1)r?rrrCr1r1r2rIsTz'Union[str, elements.BindParameter[Any]]cKsB|dkr|j}tj|||j|d}d|_|r:|j|f|S|SdS)N)type_rFT)rJr BindParametertypeZ_is_crud_compiler_dispatch)r?rrrrFrrC bindparamr1r1r2rIs cKsRd|k}|s0|jr0t|jtjr0||jd|jf<|jjrD||j}|j |f|S)NrDr) uniquer/rJrZ_truncated_labelZtruncated_namesr_isnull_with_binary_element_typer)r?rrrrCZis_cter1r1r2_handle_values_anonymous_params  rzTuple[Callable[[Union[str, ColumnClause[Any]]], Union[str, Tuple[str, str]]], Callable[[ColumnClause[Any]], Union[str, Tuple[str, str]]], _BindNameForColProtocol])r?r@rAr.cst|rj|jrjt|jttjtj dddfdd }dddfdd }dd dfd d }nttjtj }t d }}|||fS)NzUnion[ColumnClause[Any], str]zUnion[str, Tuple[str, str]])rJr.cs0|}t|dr(|jkr(|jj|fS|SdS)Nrh)hasattrrhr)rJZstr_key_etZ c_key_roler1r2rPs z4_key_getters_for_crud_column.._column_as_keyr,)rr.cs"|jkr|jj|jfS|jSdSrU)rhrrJrrr1r2r|s z6_key_getters_for_crud_column.._getattr_col_keyrcs:|jkr0trt|jtstd|jj|jfS|jSdS)Nz%s_%s)rhrr/rrbrrJrrr1r2r}s  z4_key_getters_for_crud_column.._col_bind_namerJ) rrp _extra_fromsru functoolspartialrZ expect_as_keyr DMLColumnRoleoperator attrgetter)r?r@rArPr|r}r1rr2rcs   rcc sTfddjD} |jddks,tj|jdd<g} jr|t| } jjD]$}|| krV|jrV|jj sV| |qV| D]R}||}||kr||kr| || ||j |ddfqt||| | q| rP|| |jdd}t|ts tddd d | Dd |}t|jd d| D|_||jdd<dS) Ncsg|]}jj|qSr1)rhr-)rLrrPr@r1r2rMsz1_scan_insert_from_select_cols.. selectableZinsert_from_selectr1z_Can't extend statement for INSERT..FROM SELECT to include additional default-holding column(s) rYcss|]\}}}}t|VqdSrU)repr)rL_rJr1r1r2rX@s z0_scan_insert_from_select_cols..z~. Convert the selectable to a subquery() first, or pass include_defaults=False to Insert.from_select() to skip these columns.cSsg|]\}}}}|qSr1r1)rLrexprr1r1r2rMIs )rrstackrbselectZ#include_insert_from_select_defaultsrurhridefault is_sentinelappendrarGrH&_append_param_insert_select_hasdefaultextendr/rrr0rxZ _generatermZ _raw_columns)r?r@rArr|rPr}rrrBrCcolsZadd_select_colsZcol_setrr-col_keyZins_from_selectr1rr2rs sP        rsc srt||| \} } } }}}|js*|js*t|jrvfdd|jD}t|fdd|DfddjjD}njj}t |}|r|j sjj }|j j }nd}}jrtj}nt}|j}|D]p}||}||kr||krt||||||| | ||||| n|r|jrR| rR| r@t|||| nt|||| n|jdk r|jjrr|dk rt||| || n|jdk r| r|| kr||n|js|j|nB| r|| kr||n&|jr$|jj k r$|js$t|n|jr$t|||| || ||kr||kr||q|rj|||fddjD||fS)Ncsg|] }|qSr1r1rNrOr1r2rMhsz_scan_cols..cs.g|]&}t|tr|jjkrjj|qSr1)r/rrhr-rN)r@r1r2rMls csg|]}|jkr|qSr1)rJrK) ordered_keysr1r2rMps c3s|]}|kr|VqdSrUr1rK)remaining_supplementalr1r2rXsz_scan_cols..)_get_returning_modifiersrprrbZ_parameter_orderingrurhr-rirjrk_autoincrement_columnr{#insert_null_pk_still_autoincrements_supplemental_returningr__append_param_parameter primary_key!_append_param_insert_pk_returning$_append_param_insert_pk_no_returningrr_append_param_insert_hasdefaultserver_defaultrr\nullable"_warn_pk_with_no_anticipated_value_append_param_updaterwr)r?r@rArr|rPr}rrrBrCneed_pksr_implicit_return_defaultspostfetch_lastrowidr9r:Zparameter_orderingrrautoincrement_colrZsupplemental_returningZcompiler_implicit_returningr-rr1)rPrrr@r2rtOs               rtc s`t|||| ^} } } } | sdS|jr0|j| |jr\t|j|jfdd|jDdS)Nc3s|]}|kr|VqdSrUr1rKZir_setr1r2rX,sz0_setup_delete_return_defaults..)r_return_defaults_columnsr_rrru) r?r@rArr|rPr}rrrBrCrrr1rr2rgs    rgcCs||}|jj||jd}t}t|r| rZ|jrZ|| krZ| rJd|_n|rZ|j |t |||f|t kt |rx|js||n d|||d| }n&|jr| r|jdkr|jr|| kr|r|j |n|jjrd|_t|||ft |r|js||n d|||d| }n|j|fd|i| }|jrj|r\||kr\|j |n |j |nX|jr|r|j |n|jjrd|_n*|r||kr|j |n |j || ||||fdS)NZ use_tableTz%s_m0)rFrrE)rrErE)rarGrHinclude_table_with_column_exprsrur _is_literalrrr_rrIr+rjrk_is_bind_parameterrr{rr self_grouprpr\)r?r@rAr-rrr}r_rrrrrrCr col_valueaccumulated_bind_namesr1r1r2r1s            rcCs |jdk r|jjrl|jjr^|jjr*|jjs^t}|||j ||j |jfd|i||f|j |nx|jj rt}|||j ||j |jj fd|i||f|j |n(|||j |t||f||jffn6||jjks|jdk r |j |n|jst|dS)zCreate a primary key expression in the INSERT statement where we want to populate result.inserted_primary_key and RETURNING is available. NrE)r is_sequencer{supports_sequencesoptionalsequences_optionalrurrGrHrr_is_clause_elementargr"_create_insert_prefetch_bind_paramrJrhrrrr)r?r@r-rrCrr1r1r2rsb        rcCs|jdk r*|jjrj|jjr*|jjrj|jjrj||jjkr|jjs|jdk rX|jjrX|jjsj|jdkr|jj r| ||j |t ||f||jffn>|jdkr|jdkr|js||jjk rt|n|jjrd|_dS)aoCreate a primary key expression in the INSERT statement where we want to populate result.inserted_primary_key and we cannot use RETURNING. Depending on the kind of default here we may create a bound parameter in the INSERT statement and pre-execute a default generation function, or we may use cursor.lastrowid if supported by the dialect. NT)rrr{rrrrhrrZ"preexecute_autoincrement_sequencesrrGrHrrJrrrr?r@r-rrCr1r1r2rsT   !"(     rcCs|jjr|jjr|jjr |jjst}|||j ||j |jfd|i||f|rn||krn|j |n|j s|j |n|jjrt}|||j ||j |jjfd|i||f|r||kr|j |n|j s|j |n(|||j |t||f||jffdS)NrE)rrr{rrrrurrGrHrr_rr\rrrrrJ)r?r@r-rrrCrr1r1r2r.sd       rzList[_CrudParamElementSQLExpr]zDict[str, Any]None)r?r@r-rrCr.cCst|jrD|jjr|jjr"|jjs|||j||j dfn^t |jrr|||j||jj dfn0|||j|t ||fddi||jffdS)Nr1rF)rrr{rrrrrGrHZ next_valuerrrrrJrr1r1r2resF       rcCs|j}|jdk r|jjs|jjrx|||jj||d|j|jj f|df|rj||krj|j |q|j |q|||jj||dt ||f||j ffnV|jdk r|r||kr|j |q|j |n$|r|js|js||kr|j |dS)Nrr1)ronupdaterrrrGrHrrrr_r\"_create_update_prefetch_bind_paramrJserver_onupdaterre)r?rAr@r-rrrC include_tabler1r1r2rsN    r)r?r-rrCr.cKsdSrUr1r?r-rrCr1r1r2rsrzLiteral[False]zelements.BindParameter[Any]cKsdSrUr1rr1r1r2rsz'Union[elements.BindParameter[Any], str])r?r-rrrCr.cKs*t||df||d|}|j||SN)rr)rIr]rr?r-rrrCparamr1r1r2rs cKsdSrUr1rr1r1r2rsrcKsdSrUr1rr1r1r2rscKs*t||df||d|}|j||Sr)rIr^rrr1r1r2rs c@sXeZdZdZddZddZddZdd Zej d d d d Z ej d d ddZ dS)_multiparam_columnTcCs4||_d|j|df|_||_|j|_|j|_dS)N%s_m%dr)indexrJoriginalrr)selfrrr1r1r2__init__s z_multiparam_column.__init__cKs tdSrUNotImplementedError)rotherrCr1r1r2comparesz_multiparam_column.comparecKs tdSrUr)rrCr1r1r2_copy_internals sz"_multiparam_column._copy_internalscCs"t|to |j|jko |j|jkSrU)r/rrJr)rrr1r1r2__eq__ s    z_multiparam_column.__eq__r)r.cCs t|jSz1used by default.py -> _process_execute_defaults())r_from_column_defaultrrr1r1r2_default_description_tuplesz-_multiparam_column._default_description_tuplecCs t|jSr)rrrrr1r1r2_onupdate_description_tuplesz._multiparam_column._onupdate_description_tupleN) r;r<r=Z_is_multiparam_columnrrrrr Zmemoized_propertyrrr1r1r1r2rsrint)r?r@r-rrCr.cCs|jstd|nht|jr6|j|jjf|S|jjrN|j|jf|St||}t |t j sht t ||fddi|SdS)NzINSERT value for column %s is explicitly rendered as a boundparameter in the VALUES clause; a Python-side value or SQL expression is requiredrT)rrr0rrrrrrr/rZInsertrbr)r?r@r-rrCrr1r1r2 _process_multiparam_default_bind s(   rc  Csdd|p dD} |j} t} |jD]} | jD]} | | kr.| | | ||| <| | }|j| | d}t|rt|| |f|t k|| d|}| j f}nP|j r|| }t || |fd|i|}|f}n"|j | |j|f|}d}|| |||fq.q$| D]} | jD]} | | kr$qn| jdk r| jjs| jjr|| |j| | d|j| jjf|df|j | n6|| |j| | dt|| fd|| i|| j ffn| jdk r|j | qqdS)NcSs i|]\}}ttj||qSr1)rexpectrr)rLr-rr1r1r2rTLs z1_get_update_multitable_params..r1r)rFrr)rrurr-addrrrrIr+rJrrr\rrrrrrrr)r?r@rArrr}r|rrCZnormalized_paramsrZaffected_tablestr-rrrZcbnr1r1r2rqAs                rqrZr[r6)r?r@rAinitial_valuesrPrCr.c s|}|g}|j}|dk stt|ddD]\} } g} fdd| D} |D]\} } }}| j| kr| j}t| |rt|| | |fdd| j| dfi|}q|j| | f|}nt ||| | |}| | | ||fqR| | q,|S)Nrcsi|]\}}||qSr1r1)rLrJrWrOr1r2rTsz2_extend_values_for_multiparams..rr) rlrb enumeraternrJrrrIrrrr)r?r@rArrPrCZvalues_0rr~irow extensionrcol_exprrZaccumulated_namesrJ new_paramr1rOr2rys>   ryc Cs|D]\}}||} | dk r*|| |q|j||jd} t|rb|jtjd||jdf|}n,|jr||jj r|| |j}|j| f|}| || |dfqdS)Nr)rr1) setdefaultrrrrrrrrrrrr) r?rArrrPrrCrVrWZcolkeyrr1r1r2ros$    roc Cs|j}|o|jrL|jo@|j j o@|jo@|j}d} d} n d}d} d} |r|jstt|j j} n t|j} nd} ||p|| || | fS)zdetermines RETURNING strategy, if any, for the statement. This is where it's determined what we need to fetch from the INSERT or UPDATE statement after it's invoked. NF)r{rjZ_inlinerzZinsert_executemany_returningrerdrkrrhrZinsert_returningZ_primary_tabler_Z_supports_implicit_returningZfavor_returning_over_lastrowidrr9Z!use_insertmanyvalues_wo_returningZ_sort_by_parameter_orderZ_get_sentinel_column_for_tablerpZupdate_returningrfZdelete_returningrrur-) r?r@rArBr{rrr_Zshould_implicit_return_defaultsZexplicit_returningr9r:rr1r1r2rs        rcCs>d|jj|j|jjf}t|jjdkr0|d7}t|dS)NaColumn '%s.%s' is marked as a member of the primary key for table '%s', but has no Python-side or server-side default generator indicated, nor does it indicate 'autoincrement=True' or 'nullable=True', and no explicit value is passed. Primary key columns typically may not store NULL.ra0 Note that as of SQLAlchemy 1.1, 'autoincrement=True' must be indicated explicitly for composite (e.g. multicolumn) primary keys if AUTO_INCREMENT/SERIAL/IDENTITY behavior is expected for one of the columns in the primary key. CREATE TABLE statements are impacted by this change as well on most backends.)rhfullnamerlenrr warn)r-msgr1r1r2rrs r).FN)TFN).)TN).)TN)R__doc__ __future__rrrtypingrrrrrrr r r r r rrrrrrrrbaserrrjrZschemarrrrrrr Z util.typingr!r?r"r#r$r%r&r'r(r)r*symbolr+r3rZ_CrudParamElementZ_CrudParamElementStrZ_CrudParamElementSQLExprr5r4rrIrrcrsrtrgrrrrrrrrrrrqryrorrr1r1r1r2 s                                          &6EEs=M7).  $!R,*