diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2014-02-10 16:33:48 -0500 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2014-02-10 16:33:48 -0500 |
commit | 2a25e42c08e7541fa70dfc5e6b1ac843d6d02027 (patch) | |
tree | e08634faa1ce95291d71276f71538ba50cc1aa20 | |
parent | ab738c21aa540cebf3c2f839e177146fc4b43672 (diff) | |
download | sqlalchemy-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.rst | 10 | ||||
-rw-r--r-- | lib/sqlalchemy/orm/query.py | 15 | ||||
-rw-r--r-- | test/orm/test_query.py | 18 |
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 |