API refactor
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2025-10-07 16:25:52 +09:00
parent 76d0d86211
commit 91c7e04474
1171 changed files with 81940 additions and 44117 deletions

View File

@@ -1,5 +1,5 @@
# sql/crud.py
# Copyright (C) 2005-2023 the SQLAlchemy authors and contributors
# Copyright (C) 2005-2025 the SQLAlchemy authors and contributors
# <see AUTHORS file>
#
# This module is part of SQLAlchemy and is released under
@@ -241,7 +241,7 @@ def _get_crud_params(
stmt_parameter_tuples = list(spd.items())
spd_str_key = {_column_as_key(key) for key in spd}
else:
stmt_parameter_tuples = spd = spd_str_key = None
stmt_parameter_tuples = spd_str_key = None
# if we have statement parameters - set defaults in the
# compiled params
@@ -332,6 +332,52 @@ def _get_crud_params(
.difference(check_columns)
)
if check:
if dml.isupdate(compile_state):
tables_mentioned = set(
c.table
for c, v in stmt_parameter_tuples
if isinstance(c, ColumnClause) and c.table is not None
).difference([compile_state.dml_table])
multi_not_in_from = tables_mentioned.difference(
compile_state._extra_froms
)
if tables_mentioned and (
not compile_state.is_multitable
or not compiler.render_table_with_column_in_update_from
):
if not compiler.render_table_with_column_in_update_from:
preamble = (
"Backend does not support additional "
"tables in the SET clause"
)
else:
preamble = (
"Statement is not a multi-table UPDATE statement"
)
raise exc.CompileError(
f"{preamble}; cannot "
f"""include columns from table(s) {
", ".join(f"'{t.description}'"
for t in tables_mentioned)
} in SET clause"""
)
elif multi_not_in_from:
assert compiler.render_table_with_column_in_update_from
raise exc.CompileError(
f"Multi-table UPDATE statement does not include "
"table(s) "
f"""{
", ".join(
f"'{t.description}'" for
t in multi_not_in_from)
}"""
)
raise exc.CompileError(
"Unconsumed column names: %s"
% (", ".join("%s" % (c,) for c in check))
@@ -393,9 +439,9 @@ def _create_bind_param(
process: Literal[True] = ...,
required: bool = False,
name: Optional[str] = None,
force_anonymous: bool = False,
**kw: Any,
) -> str:
...
) -> str: ...
@overload
@@ -404,8 +450,7 @@ def _create_bind_param(
col: ColumnElement[Any],
value: Any,
**kw: Any,
) -> str:
...
) -> str: ...
def _create_bind_param(
@@ -415,10 +460,14 @@ def _create_bind_param(
process: bool = True,
required: bool = False,
name: Optional[str] = None,
force_anonymous: bool = False,
**kw: Any,
) -> Union[str, elements.BindParameter[Any]]:
if name is None:
if force_anonymous:
name = None
elif name is None:
name = col.key
bindparam = elements.BindParameter(
name, value, type_=col.type, required=required
)
@@ -488,7 +537,7 @@ def _key_getters_for_crud_column(
)
def _column_as_key(
key: Union[ColumnClause[Any], str]
key: Union[ColumnClause[Any], str],
) -> Union[str, Tuple[str, str]]:
str_key = c_key_role(key)
if hasattr(key, "table") and key.table in _et:
@@ -834,6 +883,7 @@ def _append_param_parameter(
):
value = parameters.pop(col_key)
has_visiting_cte = kw.get("visiting_cte") is not None
col_value = compiler.preparer.format_column(
c, use_table=compile_state.include_table_with_column_exprs
)
@@ -859,11 +909,14 @@ def _append_param_parameter(
c,
value,
required=value is REQUIRED,
name=_col_bind_name(c)
if not _compile_state_isinsert(compile_state)
or not compile_state._has_multi_parameters
else "%s_m0" % _col_bind_name(c),
name=(
_col_bind_name(c)
if not _compile_state_isinsert(compile_state)
or not compile_state._has_multi_parameters
else "%s_m0" % _col_bind_name(c)
),
accumulate_bind_names=accumulated_bind_names,
force_anonymous=has_visiting_cte,
**kw,
)
elif value._is_bind_parameter:
@@ -884,10 +937,12 @@ def _append_param_parameter(
compiler,
c,
value,
name=_col_bind_name(c)
if not _compile_state_isinsert(compile_state)
or not compile_state._has_multi_parameters
else "%s_m0" % _col_bind_name(c),
name=(
_col_bind_name(c)
if not _compile_state_isinsert(compile_state)
or not compile_state._has_multi_parameters
else "%s_m0" % _col_bind_name(c)
),
accumulate_bind_names=accumulated_bind_names,
**kw,
)
@@ -1213,8 +1268,7 @@ def _create_insert_prefetch_bind_param(
c: ColumnElement[Any],
process: Literal[True] = ...,
**kw: Any,
) -> str:
...
) -> str: ...
@overload
@@ -1223,8 +1277,7 @@ def _create_insert_prefetch_bind_param(
c: ColumnElement[Any],
process: Literal[False],
**kw: Any,
) -> elements.BindParameter[Any]:
...
) -> elements.BindParameter[Any]: ...
def _create_insert_prefetch_bind_param(
@@ -1247,8 +1300,7 @@ def _create_update_prefetch_bind_param(
c: ColumnElement[Any],
process: Literal[True] = ...,
**kw: Any,
) -> str:
...
) -> str: ...
@overload
@@ -1257,8 +1309,7 @@ def _create_update_prefetch_bind_param(
c: ColumnElement[Any],
process: Literal[False],
**kw: Any,
) -> elements.BindParameter[Any]:
...
) -> elements.BindParameter[Any]: ...
def _create_update_prefetch_bind_param(
@@ -1288,7 +1339,7 @@ class _multiparam_column(elements.ColumnElement[Any]):
def compare(self, other, **kw):
raise NotImplementedError()
def _copy_internals(self, other, **kw):
def _copy_internals(self, **kw):
raise NotImplementedError()
def __eq__(self, other):
@@ -1364,9 +1415,28 @@ def _get_update_multitable_params(
affected_tables = set()
for t in compile_state._extra_froms:
# extra gymnastics to support the probably-shouldnt-have-supported
# case of "UPDATE table AS alias SET table.foo = bar", but it's
# supported
we_shouldnt_be_here_if_columns_found = (
not include_table
and not compile_state.dml_table.is_derived_from(t)
)
for c in t.c:
if c in normalized_params:
if we_shouldnt_be_here_if_columns_found:
raise exc.CompileError(
"Backend does not support additional tables "
"in the SET "
"clause; cannot include columns from table(s) "
f"'{t.description}' in "
"SET clause"
)
affected_tables.add(t)
check_columns[_getattr_col_key(c)] = c
value = normalized_params[c]
@@ -1392,6 +1462,7 @@ def _get_update_multitable_params(
value = compiler.process(value.self_group(), **kw)
accumulated_bind_names = ()
values.append((c, col_value, value, accumulated_bind_names))
# determine tables which are actually to be updated - process onupdate
# and server_onupdate for these
for t in affected_tables:
@@ -1437,6 +1508,7 @@ def _extend_values_for_multiparams(
values_0 = initial_values
values = [initial_values]
has_visiting_cte = kw.get("visiting_cte") is not None
mp = compile_state._multi_parameters
assert mp is not None
for i, row in enumerate(mp[1:]):
@@ -1453,7 +1525,8 @@ def _extend_values_for_multiparams(
compiler,
col,
row[key],
name="%s_m%d" % (col.key, i + 1),
name=("%s_m%d" % (col.key, i + 1)),
force_anonymous=has_visiting_cte,
**kw,
)
else: