summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/orm
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2018-06-01 16:54:11 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2018-06-04 11:42:49 -0400
commit5628da627c4f248a817eafd72ecdf4793809f68d (patch)
treef3fb07bce5108345e2ff7ca8776271205def7100 /lib/sqlalchemy/orm
parent45b22c9c3fd8fc0d2c80ec00ef9070837cd18063 (diff)
downloadsqlalchemy-5628da627c4f248a817eafd72ecdf4793809f68d.tar.gz
Support undocumented non-entity sequence Query argument
Fixed regression caused by :ticket:`4256` (itself a regression fix for :ticket:`4228`) which breaks an undocumented behavior which converted for a non-sequence of entities passed directly to the :class:`.Query` constructor into a single-element sequence. While this behavior was never supported or documented, it's already in use so has been added as a behavioral contract to :class:`.Query`. Change-Id: I97546f5ab5af29f37c86321f39d564f98a12daf5 Fixes: #4269
Diffstat (limited to 'lib/sqlalchemy/orm')
-rw-r--r--lib/sqlalchemy/orm/query.py22
1 files changed, 21 insertions, 1 deletions
diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py
index 56e42a702..8f6042a2b 100644
--- a/lib/sqlalchemy/orm/query.py
+++ b/lib/sqlalchemy/orm/query.py
@@ -147,7 +147,27 @@ class Query(object):
self._entities = []
self._primary_entity = None
self._has_mapper_entities = False
- if entities:
+
+ # 1. don't run util.to_list() or _set_entity_selectables
+ # if no entities were passed - major performance bottleneck
+ # from lazy loader implementation when it seeks to use Query
+ # class for an identity lookup, causes test_orm.py to fail
+ # with thousands of extra function calls, see issue #4228
+ # for why this use had to be added
+ # 2. can't use classmethod on Query because session.query_cls
+ # is an arbitrary callable in some user recipes, not
+ # necessarily a class, so we don't have the class available.
+ # see issue #4256
+ # 3. can't do "if entities is not None" because we usually get here
+ # from session.query() which takes in *entities.
+ # 4. can't do "if entities" because users make use of undocumented
+ # to_list() behavior here and they pass clause expressions that
+ # can't be evaluated as boolean. See issue #4269.
+ # 5. the empty tuple is a singleton in cPython, take advantage of this
+ # so that we can skip for the empty "*entities" case without using
+ # any Python overloadable operators.
+ #
+ if entities is not ():
for ent in util.to_list(entities):
entity_wrapper(self, ent)