diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2020-04-24 15:34:19 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2020-05-02 11:18:13 -0400 |
| commit | bbf644862ab05734d153d74abf59aa3492278563 (patch) | |
| tree | 0a563147603ff2906422ed1b07e9f5f03e7584c8 /lib/sqlalchemy/ext | |
| parent | 7acf9af1ce74a0bda4c4d29af7da543b5c42b3f8 (diff) | |
| download | sqlalchemy-bbf644862ab05734d153d74abf59aa3492278563.tar.gz | |
Integrate new Result into ORM query
The next step in the 2.0 ORM changes is to have the
ORM integrate with the new Result object fully.
this patch uses Result to represent ORM objects rather
than lists. public API to get at this Result is not
added yet. dogpile.cache and horizontal sharding
recipe/extensions have small adjustments to accommodate
this change.
Callcounts have fluctuated, some slightly better and
some slightly worse. A few have gone up by a bit,
however as the codebase is still in flux it is anticipated
there will be some performance gains later on as
ORM fetching is refined to no longer need to accommodate
for extensive aliasing. The addition of caching
will then change the entire story.
References: #5087
References: #4395
Change-Id: If1a23824ffb77d8d58cf2338cf35dd6b5963b17f
Diffstat (limited to 'lib/sqlalchemy/ext')
| -rw-r--r-- | lib/sqlalchemy/ext/baked.py | 7 | ||||
| -rw-r--r-- | lib/sqlalchemy/ext/horizontal_shard.py | 25 |
2 files changed, 21 insertions, 11 deletions
diff --git a/lib/sqlalchemy/ext/baked.py b/lib/sqlalchemy/ext/baked.py index e5e31c1f9..ca07be784 100644 --- a/lib/sqlalchemy/ext/baked.py +++ b/lib/sqlalchemy/ext/baked.py @@ -425,9 +425,12 @@ class Result(object): return str(self._as_query()) def __iter__(self): + return iter(self._iter()) + + def _iter(self): bq = self.bq if not self.session.enable_baked_queries or bq._spoiled: - return iter(self._as_query()) + return self._as_query()._iter() baked_context = bq._bakery.get(bq._effective_key(self.session), None) if baked_context is None: @@ -548,7 +551,7 @@ class Result(object): Equivalent to :meth:`_query.Query.all`. """ - return list(self) + return self._iter().all() def get(self, ident): """Retrieve an object based on identity. diff --git a/lib/sqlalchemy/ext/horizontal_shard.py b/lib/sqlalchemy/ext/horizontal_shard.py index aa2921498..931f45699 100644 --- a/lib/sqlalchemy/ext/horizontal_shard.py +++ b/lib/sqlalchemy/ext/horizontal_shard.py @@ -15,12 +15,13 @@ the source distribution. """ +import copy + from .. import inspect from .. import util from ..orm.query import Query from ..orm.session import Session - __all__ = ["ShardedSession", "ShardedQuery"] @@ -44,11 +45,18 @@ class ShardedQuery(Query): def _execute_and_instances(self, context): def iter_for_shard(shard_id): - context.attributes["shard_id"] = context.identity_token = shard_id - result = self._connection_from_session( + # shallow copy, so that each context may be used by + # ORM load events and similar. + copied_context = copy.copy(context) + copied_context.attributes = context.attributes.copy() + + copied_context.attributes[ + "shard_id" + ] = copied_context.identity_token = shard_id + result_ = self._connection_from_session( mapper=self._bind_mapper(), shard_id=shard_id - ).execute(context.statement, self._params) - return self.instances(result, context) + ).execute(copied_context.statement, self._params) + return self.instances(result_, copied_context) if context.identity_token is not None: return iter_for_shard(context.identity_token) @@ -57,11 +65,10 @@ class ShardedQuery(Query): else: partial = [] for shard_id in self.query_chooser(self): - partial.extend(iter_for_shard(shard_id)) + result_ = iter_for_shard(shard_id) + partial.append(result_) - # if some kind of in memory 'sorting' - # were done, this is where it would happen - return iter(partial) + return partial[0].merge(*partial[1:]) def _execute_crud(self, stmt, mapper): def exec_for_shard(shard_id): |
