summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2014-02-10 16:33:48 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2014-02-10 16:33:48 -0500
commit2a25e42c08e7541fa70dfc5e6b1ac843d6d02027 (patch)
treee08634faa1ce95291d71276f71538ba50cc1aa20
parentab738c21aa540cebf3c2f839e177146fc4b43672 (diff)
downloadsqlalchemy-2a25e42c08e7541fa70dfc5e6b1ac843d6d02027.tar.gz
- Fixed bug where :meth:`.Query.get` would fail to consistently
raise the :class:`.InvalidRequestError` that invokes when called on a query with existing criterion, when the given identity is already present in the identity map. [ticket:2951]
-rw-r--r--doc/build/changelog/changelog_08.rst10
-rw-r--r--lib/sqlalchemy/orm/query.py15
-rw-r--r--test/orm/test_query.py18
3 files changed, 39 insertions, 4 deletions
diff --git a/doc/build/changelog/changelog_08.rst b/doc/build/changelog/changelog_08.rst
index 58804899b..860a18a1e 100644
--- a/doc/build/changelog/changelog_08.rst
+++ b/doc/build/changelog/changelog_08.rst
@@ -12,6 +12,16 @@
:version: 0.8.5
.. change::
+ :tags: bug, orm
+ :tickets: 2951
+ :versions: 0.9.3
+
+ Fixed bug where :meth:`.Query.get` would fail to consistently
+ raise the :class:`.InvalidRequestError` that invokes when called
+ on a query with existing criterion, when the given identity is
+ already present in the identity map.
+
+ .. change::
:tags: bug, mysql
:tickets: 2933
:versions: 0.9.3
diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py
index 949c7eff9..d28f9a715 100644
--- a/lib/sqlalchemy/orm/query.py
+++ b/lib/sqlalchemy/orm/query.py
@@ -338,20 +338,26 @@ class Query(object):
return equivs
def _get_condition(self):
- self._order_by = self._distinct = False
- return self._no_criterion_condition("get")
+ return self._no_criterion_condition("get", order_by=False, distinct=False)
- def _no_criterion_condition(self, meth):
+ def _get_existing_condition(self):
+ self._no_criterion_assertion("get", order_by=False, distinct=False)
+
+ def _no_criterion_assertion(self, meth, order_by=True, distinct=True):
if not self._enable_assertions:
return
if self._criterion is not None or \
self._statement is not None or self._from_obj or \
self._limit is not None or self._offset is not None or \
- self._group_by or self._order_by or self._distinct:
+ self._group_by or (order_by and self._order_by) or \
+ (distinct and self._distinct):
raise sa_exc.InvalidRequestError(
"Query.%s() being called on a "
"Query with existing criterion. " % meth)
+ def _no_criterion_condition(self, meth, order_by=True, distinct=True):
+ self._no_criterion_assertion(meth, order_by, distinct)
+
self._from_obj = ()
self._statement = self._criterion = None
self._order_by = self._group_by = self._distinct = False
@@ -800,6 +806,7 @@ class Query(object):
instance = loading.get_from_identity(
self.session, key, attributes.PASSIVE_OFF)
if instance is not None:
+ self._get_existing_condition()
# reject calls for id in identity map but class
# mismatch.
if not issubclass(instance.__class__, mapper.class_):
diff --git a/test/orm/test_query.py b/test/orm/test_query.py
index dbac48580..3d88dce56 100644
--- a/test/orm/test_query.py
+++ b/test/orm/test_query.py
@@ -455,6 +455,24 @@ class GetTest(QueryTest):
# order_by()/get() doesn't raise
s.query(User).order_by(User.id).get(8)
+ def test_no_criterion_when_already_loaded(self):
+ """test that get()/load() does not use preexisting filter/etc. criterion,
+ even when we're only using the identity map."""
+
+ User, Address = self.classes.User, self.classes.Address
+
+
+ s = create_session()
+
+ u1 = s.query(User).get(7)
+
+ q = s.query(User).join('addresses').filter(Address.user_id==8)
+ assert_raises(sa_exc.InvalidRequestError, q.get, 7)
+ assert_raises(sa_exc.InvalidRequestError, s.query(User).filter(User.id==7).get, 19)
+
+ # order_by()/get() doesn't raise
+ s.query(User).order_by(User.id).get(8)
+
def test_unique_param_names(self):
users = self.tables.users