From: Mike Bayer Date: Thu, 6 Dec 2007 19:15:04 +0000 (+0000) Subject: - query.get() and query.load() do not take existing filter or other X-Git-Tag: rel_0_4_2~102 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=4580e77da28ee9bf98c109e8f7a81cb569112dcc;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - query.get() and query.load() do not take existing filter or other criterion into account; these methods *always* look up the given id in the database or return the current instance from the identity map, disregarding any existing filter, join, group_by or other criterion which has been configured. [ticket:893] --- diff --git a/CHANGES b/CHANGES index 791d4d6ef2..d73ea69f08 100644 --- a/CHANGES +++ b/CHANGES @@ -43,7 +43,13 @@ CHANGES convenient than using dynamic relations in some cases; for those who have not, you might notice your apps using a lot fewer queries than before in some situations. [ticket:871] - + + - query.get() and query.load() do not take existing filter or other + criterion into account; these methods *always* look up the given id + in the database or return the current instance from the identity map, + disregarding any existing filter, join, group_by or other criterion + which has been configured. [ticket:893] + - new synonym() behavior: an attribute will be placed on the mapped class, if one does not exist already, in all cases. if a property already exists on the class, the synonym will decorate the property diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py index 054ac04e74..eb0d49147c 100644 --- a/lib/sqlalchemy/orm/query.py +++ b/lib/sqlalchemy/orm/query.py @@ -52,6 +52,15 @@ class Query(object): self._primary_adapter=None self._only_load_props = None self._refresh_instance = None + + def _no_criterion(self): + q = self._clone() + q._from_obj = [self.table] + q._alias_ids = {} + q._joinpoint = self.mapper + q._statement = q._aliases = q._criterion = None + q._order_by = q._group_by = q._distinct = False + return q def _clone(self): q = Query.__new__(Query) @@ -757,8 +766,8 @@ class Query(object): ident = util.to_list(ident) q = self - if ident is not None: + q = q._no_criterion() params = {} (_get_clause, _get_params) = self.select_mapper._get_clause q = q.filter(_get_clause) diff --git a/test/orm/query.py b/test/orm/query.py index f1b40e0b1a..158576f176 100644 --- a/test/orm/query.py +++ b/test/orm/query.py @@ -60,7 +60,33 @@ class GetTest(QueryTest): s.clear() u2 = s.query(User).get(7) assert u is not u2 + + def test_no_criterion(self): + """test that get()/load() does not use preexisting filter/etc. criterion""" + + s = create_session() + + assert s.query(User).filter(User.id==7).get(19) is None + + u = s.query(User).get(7) + assert s.query(User).filter(User.id==9).get(7) is u + s.clear() + assert s.query(User).filter(User.id==9).get(7).id == u.id + # user 10 has no addresses + u = s.query(User).get(10) + assert s.query(User).join('addresses').get(10) is u + s.clear() + assert s.query(User).join('addresses').get(10).id == u.id + + u = s.query(User).get(7) + assert s.query(User).join('addresses').filter(Address.user_id==8).filter(User.id==7).first() is None + assert s.query(User).join('addresses').filter(Address.user_id==8).get(7) is u + s.clear() + assert s.query(User).join('addresses').filter(Address.user_id==8).get(7).id == u.id + + assert s.query(User).join('addresses').filter(Address.user_id==8).load(7).id == u.id + def test_unique_param_names(self): class SomeUser(object): pass