From 16d21f6401436c1f5fd3aff6c09857bf6e222ced Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Mon, 13 Mar 2006 02:53:51 +0000 Subject: [PATCH] added selectfirst_by/selectone_by, selectone throws exception if more than one row returned, courtesy J.Ellis --- CHANGES | 3 +++ lib/sqlalchemy/mapping/mapper.py | 45 ++++++++++++++++++++------------ 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/CHANGES b/CHANGES index b22f271a9e..72890daca2 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,9 @@ correctly, also relations set up against a mapper with inherited mappers will create joins against the table that is specific to the mapper itself (i.e. and not any tables that are inherited/are further down the inheritance chain), this can be overridden by using custom primary/secondary joins. +- added J.Ellis patch to mapper.py so that selectone() throws an exception +if query returns more than one object row, selectfirst() to not throw the +exception. also adds selectfirst_by (synonymous with get_by) and selectone_by - added onupdate parameter to Column, will exec SQL/python upon an update statement.Also adds "for_update=True" to all DefaultGenerator subclasses - added user-contributed support for Oracle table reflection; still diff --git a/lib/sqlalchemy/mapping/mapper.py b/lib/sqlalchemy/mapping/mapper.py index a77c2db12f..7254d70bdc 100644 --- a/lib/sqlalchemy/mapping/mapper.py +++ b/lib/sqlalchemy/mapping/mapper.py @@ -253,7 +253,7 @@ class Mapper(object): populate_existing = kwargs.get('populate_existing', False) result = util.HistoryArraySet() - if len(mappers): + if mappers: otherresults = [] for m in mappers: otherresults.append(util.HistoryArraySet()) @@ -273,10 +273,9 @@ class Mapper(object): for value in imap.values(): objectstore.get_session().register_clean(value) - if len(mappers): - return [result] + otherresults - else: - return result + if mappers: + result.extend(otherresults) + return result def get(self, *ident): """returns an instance of the object based on the given identifier, or None @@ -374,7 +373,7 @@ class Mapper(object): e.g. u = usermapper.get_by(user_name = 'fred') """ x = self.select_whereclause(self._by_clause(*args, **params), limit=1) - if len(x): + if x: return x[0] else: return None @@ -393,6 +392,18 @@ class Mapper(object): e.g. result = usermapper.select_by(user_name = 'fred') """ return self.select_whereclause(self._by_clause(*args, **params)) + + def selectfirst_by(self, *args, **params): + """works like select_by(), but only returns the first result by itself, or None if no + objects returned. Synonymous with get_by()""" + return self.get_by(*args, **params) + + def selectone_by(self, *args, **params): + """works like selectfirst(), but throws an error if not exactly one result was returned.""" + ret = self.select_by(*args, **params) + if len(ret) == 1: + return ret[0] + raise InvalidRequestError('Multiple rows returned for selectone') def count_by(self, *args, **params): """returns the count of instances based on the given clauses and key/value criterion. @@ -448,16 +459,23 @@ class Mapper(object): else: raise AttributeError(key) - def selectone(self, *args, **params): + def selectfirst(self, *args, **params): """works like select(), but only returns the first result by itself, or None if no objects returned.""" params['limit'] = 1 ret = self.select(*args, **params) - if len(ret): + if ret: return ret[0] else: return None + def selectone(self, *args, **params): + """works like selectfirst(), but throws an error if not exactly one result was returned.""" + ret = self.select(*args, **params) + if len(ret) == 1: + return ret[0] + raise InvalidRequestError('Multiple rows returned for selectone') + def select(self, arg = None, **kwargs): """selects instances of the object from the database. @@ -983,12 +1001,5 @@ def class_mapper(class_): """given a class, returns the primary Mapper associated with the class.""" try: return mapper_registry[class_] - except KeyError: - pass - except AttributeError: - pass - raise InvalidRequestError("Class '%s' has no mapper associated with it" % class_.__name__) - - - - + except (KeyError, AttributeError): + raise InvalidRequestError("Class '%s' has no mapper associated with it" % class_.__name__) -- 2.47.2