diff options
| author | mike bayer <mike_mp@zzzcomputing.com> | 2023-04-09 14:32:09 +0000 |
|---|---|---|
| committer | Gerrit Code Review <gerrit@bbpush.zzzcomputing.com> | 2023-04-09 14:32:09 +0000 |
| commit | 1eb72d9725d0df60206151805c927ad3c6566fb7 (patch) | |
| tree | 7ee934cda3333a0e5a1277ef4808eba08eb61955 /lib/sqlalchemy | |
| parent | 4c54a0339c82771b7e392324c960cd6fd6751295 (diff) | |
| parent | 8ad3dd4c039c0ff0da069f3b67936d9bc26d6154 (diff) | |
| download | sqlalchemy-1eb72d9725d0df60206151805c927ad3c6566fb7.tar.gz | |
Merge "optimize exec defaults a bit" into main
Diffstat (limited to 'lib/sqlalchemy')
| -rw-r--r-- | lib/sqlalchemy/engine/default.py | 110 | ||||
| -rw-r--r-- | lib/sqlalchemy/sql/schema.py | 5 |
2 files changed, 59 insertions, 56 deletions
diff --git a/lib/sqlalchemy/engine/default.py b/lib/sqlalchemy/engine/default.py index 3e4e6fb9a..462473de2 100644 --- a/lib/sqlalchemy/engine/default.py +++ b/lib/sqlalchemy/engine/default.py @@ -62,7 +62,6 @@ from ..sql.base import _NoArg from ..sql.compiler import DDLCompiler from ..sql.compiler import SQLCompiler from ..sql.elements import quoted_name -from ..sql.schema import default_is_scalar from ..util.typing import Final from ..util.typing import Literal @@ -1203,10 +1202,7 @@ class DefaultExecutionContext(ExecutionContext): self.cursor = self.create_cursor() if self.compiled.insert_prefetch or self.compiled.update_prefetch: - if self.executemany: - self._process_executemany_defaults() - else: - self._process_executesingle_defaults() + self._process_execute_defaults() processors = compiled._bind_processors @@ -1907,11 +1903,15 @@ class DefaultExecutionContext(ExecutionContext): if default.is_sequence: return self.fire_sequence(default, type_) elif default.is_callable: + # this codepath is not normally used as it's inlined + # into _process_execute_defaults self.current_column = column return default.arg(self) elif default.is_clause_element: return self._exec_default_clause_element(column, default, type_) else: + # this codepath is not normally used as it's inlined + # into _process_execute_defaults return default.arg def _exec_default_clause_element(self, column, default, type_): @@ -2054,68 +2054,68 @@ class DefaultExecutionContext(ExecutionContext): else: return self._exec_default(column, column.onupdate, column.type) - def _process_executemany_defaults(self): + def _process_execute_defaults(self): compiled = cast(SQLCompiler, self.compiled) key_getter = compiled._within_exec_param_key_getter - scalar_defaults: Dict[Column[Any], Any] = {} - - insert_prefetch = compiled.insert_prefetch - update_prefetch = compiled.update_prefetch - # pre-determine scalar Python-side defaults # to avoid many calls of get_insert_default()/ # get_update_default() - for c in insert_prefetch: - if c.default and default_is_scalar(c.default): - scalar_defaults[c] = c.default.arg - - for c in update_prefetch: - if c.onupdate and default_is_scalar(c.onupdate): - scalar_defaults[c] = c.onupdate.arg + if compiled.insert_prefetch: + prefetch_recs = [ + ( + c, + key_getter(c), + ( + c.default.arg, # type: ignore + c.default.is_scalar, + c.default.is_callable, + ) + if c.default and c.default.has_arg + else (None, None, None), + self.get_insert_default, + ) + for c in compiled.insert_prefetch + ] + elif compiled.update_prefetch: + prefetch_recs = [ + ( + c, + key_getter(c), + ( + c.onupdate.arg, # type: ignore + c.onupdate.is_scalar, + c.onupdate.is_callable, + ) + if c.onupdate and c.onupdate.has_arg + else (None, None, None), + self.get_update_default, + ) + for c in compiled.update_prefetch + ] + else: + prefetch_recs = [] for param in self.compiled_parameters: self.current_parameters = param - for c in insert_prefetch: - if c in scalar_defaults: - val = scalar_defaults[c] - else: - val = self.get_insert_default(c) - if val is not None: - param[key_getter(c)] = val - for c in update_prefetch: - if c in scalar_defaults: - val = scalar_defaults[c] - else: - val = self.get_update_default(c) - if val is not None: - param[key_getter(c)] = val - - del self.current_parameters - - def _process_executesingle_defaults(self): - compiled = cast(SQLCompiler, self.compiled) - key_getter = compiled._within_exec_param_key_getter - self.current_parameters = ( - compiled_parameters - ) = self.compiled_parameters[0] - - for c in compiled.insert_prefetch: - if c.default and default_is_scalar(c.default): - val = c.default.arg - else: - val = self.get_insert_default(c) - - if val is not None: - compiled_parameters[key_getter(c)] = val - - for c in compiled.update_prefetch: - val = self.get_update_default(c) + for ( + c, + param_key, + (arg, is_scalar, is_callable), + fallback, + ) in prefetch_recs: + if is_scalar: + param[param_key] = arg + elif is_callable: + self.current_column = c + param[param_key] = arg(self) # type: ignore + else: + val = fallback(c) + if val is not None: + param[param_key] = val - if val is not None: - compiled_parameters[key_getter(c)] = val del self.current_parameters diff --git a/lib/sqlalchemy/sql/schema.py b/lib/sqlalchemy/sql/schema.py index b4263137b..ab56d2552 100644 --- a/lib/sqlalchemy/sql/schema.py +++ b/lib/sqlalchemy/sql/schema.py @@ -3093,6 +3093,7 @@ class DefaultGenerator(Executable, SchemaItem): is_clause_element = False is_callable = False is_scalar = False + has_arg = False column: Optional[Column[Any]] def __init__(self, for_update: bool = False) -> None: @@ -3234,6 +3235,7 @@ class ScalarElementColumnDefault(ColumnDefault): """ is_scalar = True + has_arg = True def __init__(self, arg: Any, for_update: bool = False) -> None: self.for_update = for_update @@ -3256,7 +3258,7 @@ class ColumnElementColumnDefault(ColumnDefault): """ is_clause_element = True - + has_arg = True arg: _SQLExprDefault def __init__( @@ -3294,6 +3296,7 @@ class CallableColumnDefault(ColumnDefault): is_callable = True arg: _CallableColumnDefaultProtocol + has_arg = True def __init__( self, |
