diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2020-04-27 12:58:12 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2020-05-25 13:56:37 -0400 |
| commit | 6930dfc032c3f9f474e71ab4e021c0ef8384930e (patch) | |
| tree | 34b919a3c34edaffda1750f161a629fc5b9a8020 /lib/sqlalchemy/sql/coercions.py | |
| parent | dce8c7a125cb99fad62c76cd145752d5afefae36 (diff) | |
| download | sqlalchemy-6930dfc032c3f9f474e71ab4e021c0ef8384930e.tar.gz | |
Convert execution to move through Session
This patch replaces the ORM execution flow with a
single pathway through Session.execute() for all queries,
including Core and ORM.
Currently included is full support for ORM Query,
Query.from_statement(), select(), as well as the
baked query and horizontal shard systems. Initial
changes have also been made to the dogpile caching
example, which like baked query makes use of a
new ORM-specific execution hook that replaces the
use of both QueryEvents.before_compile() as well
as Query._execute_and_instances() as the central
ORM interception hooks.
select() and Query() constructs alike can be passed to
Session.execute() where they will return ORM
results in a Results object. This API is currently
used internally by Query. Full support for
Session.execute()->results to behave in a fully
2.0 fashion will be in later changesets.
bulk update/delete with ORM support will also
be delivered via the update() and delete()
constructs, however these have not yet been adapted
to the new system and may follow in a subsequent
update.
Performance is also beginning to lag as of this
commit and some previous ones. It is hoped that
a few central functions such as the coercions
functions can be rewritten in C to re-gain
performance. Additionally, query caching
is now available and some subsequent patches
will attempt to cache more of the per-execution
work from the ORM layer, e.g. column getters
and adapters.
This patch also contains initial "turn on" of the
caching system enginewide via the query_cache_size
parameter to create_engine(). Still defaulting at
zero for "no caching". The caching system still
needs adjustments in order to gain adequate performance.
Change-Id: I047a7ebb26aa85dc01f6789fac2bff561dcd555d
Diffstat (limited to 'lib/sqlalchemy/sql/coercions.py')
| -rw-r--r-- | lib/sqlalchemy/sql/coercions.py | 57 |
1 files changed, 28 insertions, 29 deletions
diff --git a/lib/sqlalchemy/sql/coercions.py b/lib/sqlalchemy/sql/coercions.py index 2fc63b82f..d8ef0222a 100644 --- a/lib/sqlalchemy/sql/coercions.py +++ b/lib/sqlalchemy/sql/coercions.py @@ -50,19 +50,26 @@ def _document_text_coercion(paramname, meth_rst, param_rst): ) -def expect(role, element, **kw): +def expect(role, element, apply_propagate_attrs=None, **kw): # major case is that we are given a ClauseElement already, skip more # elaborate logic up front if possible impl = _impl_lookup[role] if not isinstance( element, - (elements.ClauseElement, schema.SchemaItem, schema.FetchedValue,), + (elements.ClauseElement, schema.SchemaItem, schema.FetchedValue), ): resolved = impl._resolve_for_clause_element(element, **kw) else: resolved = element + if ( + apply_propagate_attrs is not None + and not apply_propagate_attrs._propagate_attrs + and resolved._propagate_attrs + ): + apply_propagate_attrs._propagate_attrs = resolved._propagate_attrs + if impl._role_class in resolved.__class__.__mro__: if impl._post_coercion: resolved = impl._post_coercion(resolved, **kw) @@ -106,32 +113,32 @@ class RoleImpl(object): self.name = role_class._role_name self._use_inspection = issubclass(role_class, roles.UsesInspection) - def _resolve_for_clause_element( - self, element, argname=None, apply_plugins=None, **kw - ): + def _resolve_for_clause_element(self, element, argname=None, **kw): original_element = element is_clause_element = False + while hasattr(element, "__clause_element__"): is_clause_element = True if not getattr(element, "is_clause_element", False): element = element.__clause_element__() else: - break - - should_apply_plugins = ( - apply_plugins is not None - and apply_plugins._compile_state_plugin is None - ) + return element + + if not is_clause_element: + if self._use_inspection: + insp = inspection.inspect(element, raiseerr=False) + if insp is not None: + insp._post_inspect + try: + element = insp.__clause_element__() + except AttributeError: + self._raise_for_expected(original_element, argname) + else: + return element - if is_clause_element: - if ( - should_apply_plugins - and "compile_state_plugin" in element._annotations - ): - apply_plugins._compile_state_plugin = element._annotations[ - "compile_state_plugin" - ] + return self._literal_coercion(element, argname=argname, **kw) + else: return element if self._use_inspection: @@ -142,14 +149,6 @@ class RoleImpl(object): element = insp.__clause_element__() except AttributeError: self._raise_for_expected(original_element, argname) - else: - if ( - should_apply_plugins - and "compile_state_plugin" in element._annotations - ): - plugin = element._annotations["compile_state_plugin"] - apply_plugins._compile_state_plugin = plugin - return element return self._literal_coercion(element, argname=argname, **kw) @@ -649,8 +648,8 @@ class SelectStatementImpl(_NoTextCoercion, RoleImpl): self._raise_for_expected(original_element, argname, resolved) -class HasCTEImpl(ReturnsRowsImpl, roles.HasCTERole): - pass +class HasCTEImpl(ReturnsRowsImpl): + __slots__ = () class JoinTargetImpl(RoleImpl): |
