summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/ext
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2020-04-24 15:34:19 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2020-05-02 11:18:13 -0400
commitbbf644862ab05734d153d74abf59aa3492278563 (patch)
tree0a563147603ff2906422ed1b07e9f5f03e7584c8 /lib/sqlalchemy/ext
parent7acf9af1ce74a0bda4c4d29af7da543b5c42b3f8 (diff)
downloadsqlalchemy-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.py7
-rw-r--r--lib/sqlalchemy/ext/horizontal_shard.py25
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):