From 5b71858533ea153dec119b3592631fdb1500a15f Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Thu, 24 Sep 2015 13:52:25 -0400 Subject: [PATCH] - replicate Query.one_or_none to BakedQuery - changelog / version note finishing --- doc/build/changelog/changelog_10.rst | 13 +++++++++---- lib/sqlalchemy/ext/baked.py | 20 ++++++++++++++++++++ lib/sqlalchemy/orm/query.py | 12 ++++++++++-- test/ext/test_baked.py | 20 ++++++++++++++++++++ 4 files changed, 59 insertions(+), 6 deletions(-) diff --git a/doc/build/changelog/changelog_10.rst b/doc/build/changelog/changelog_10.rst index 5c5ffed1d6..ef125eecff 100644 --- a/doc/build/changelog/changelog_10.rst +++ b/doc/build/changelog/changelog_10.rst @@ -18,6 +18,15 @@ .. changelog:: :version: 1.0.9 + .. change:: + :tags: feature, orm + :versions: 1.1.0b1 + :pullreq: github:201 + + Added new method :meth:`.Query.one_or_none`; same as + :meth:`.Query.one` but returns None if no row found. Pull request + courtesy esiegerman. + .. change:: :tags: bug, orm :versions: 1.1.0b1 @@ -90,10 +99,6 @@ to again work as it is based on an 8.0.x version of Postgresql. Fix courtesy Pete Hollobon. - .. change:: - :tags: orm - - Add Query.one_or_none() method. .. changelog:: :version: 1.0.8 diff --git a/lib/sqlalchemy/ext/baked.py b/lib/sqlalchemy/ext/baked.py index f01e0b348d..a933e7eb71 100644 --- a/lib/sqlalchemy/ext/baked.py +++ b/lib/sqlalchemy/ext/baked.py @@ -283,6 +283,26 @@ class Result(object): raise orm_exc.MultipleResultsFound( "Multiple rows were found for one()") + def one_or_none(self): + """Return one or zero results, or raise an exception for multiple + rows. + + Equivalent to :meth:`.Query.one_or_none`. + + .. versionadded:: 1.0.9 + + """ + ret = list(self) + + l = len(ret) + if l == 1: + return ret[0] + elif l == 0: + return None + else: + raise orm_exc.MultipleResultsFound( + "Multiple rows were found for one()") + def all(self): """Return all rows. diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py index 8c4925905d..f0b8969a2a 100644 --- a/lib/sqlalchemy/orm/query.py +++ b/lib/sqlalchemy/orm/query.py @@ -2491,8 +2491,10 @@ class Query(object): Calling ``one_or_none()`` results in an execution of the underlying query. - .. versionchanged:: 1.0.9 - Added ``one_or_none()`` + .. versionadded:: 1.0.9 + + Added :meth:`.Query.one_or_none` + """ ret = list(self) @@ -2526,6 +2528,12 @@ class Query(object): any kind of limit, so that the "unique"-ing of entities does not conceal multiple object identities. + .. seealso:: + + :meth:`.Query.first` + + :meth:`.Query.one_or_none` + """ ret = list(self) diff --git a/test/ext/test_baked.py b/test/ext/test_baked.py index 78c43fc7e0..ae335db025 100644 --- a/test/ext/test_baked.py +++ b/test/ext/test_baked.py @@ -151,6 +151,26 @@ class LikeQueryTest(BakedTest): (8, ) ) + def test_one_or_none_no_result(self): + User = self.classes.User + + bq = self.bakery(lambda s: s.query(User)) + bq += lambda q: q.filter(User.name == 'asdf') + + eq_( + bq(Session()).one_or_none(), + None + ) + + def test_one_or_none_result(self): + User = self.classes.User + + bq = self.bakery(lambda s: s.query(User)) + bq += lambda q: q.filter(User.name == 'ed') + + u1 = bq(Session()).one_or_none() + eq_(u1.name, 'ed') + def test_one_no_result(self): User = self.classes.User -- 2.47.3