From a1fe6e2c7607740c46eaab89e2bcd70aaccee71e Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Wed, 20 Jun 2007 22:28:54 +0000 Subject: [PATCH] - forwards-compatibility with 0.4: added one(), first(), and all() to Query - added selectone_by() to assignmapper --- CHANGES | 6 +++- lib/sqlalchemy/ext/assignmapper.py | 2 +- lib/sqlalchemy/orm/query.py | 45 ++++++++++++++++++++++++++++-- test/orm/inheritance5.py | 2 ++ 4 files changed, 51 insertions(+), 4 deletions(-) diff --git a/CHANGES b/CHANGES index 393c6a2882..5e3f960d01 100644 --- a/CHANGES +++ b/CHANGES @@ -8,6 +8,8 @@ - association proxies no longer bind tightly to source collections [ticket:597], and are constructed with a thunk instead - orm + - forwards-compatibility with 0.4: added one(), first(), and + all() to Query - added synchronization to the mapper() construction step, to avoid thread collections when pre-existing mappers are compiling in a different thread [ticket:613] @@ -42,7 +44,9 @@ - sqlite better handles datetime/date/time objects mixed and matched with various Date/Time/DateTime columns - string PK column inserts dont get overwritten with OID [ticket:603] - +- extensions + - added selectone_by() to assignmapper + 0.3.8 - engines - added detach() to Connection, allows underlying DBAPI connection diff --git a/lib/sqlalchemy/ext/assignmapper.py b/lib/sqlalchemy/ext/assignmapper.py index b124de8f6d..4708afd8dd 100644 --- a/lib/sqlalchemy/ext/assignmapper.py +++ b/lib/sqlalchemy/ext/assignmapper.py @@ -43,7 +43,7 @@ def assign_mapper(ctx, class_, *args, **kwargs): m = mapper(class_, extension=extension, *args, **kwargs) class_.mapper = m class_.query = classmethod(lambda cls: Query(class_, session=ctx.current)) - for name in ['get', 'filter', 'filter_by', 'select', 'select_by', 'selectfirst', 'selectfirst_by', 'selectone', 'get_by', 'join_to', 'join_via', 'count', 'count_by', 'options', 'instances']: + for name in ['get', 'filter', 'filter_by', 'select', 'select_by', 'selectfirst', 'selectfirst_by', 'selectone', 'selectone_by', 'get_by', 'join_to', 'join_via', 'count', 'count_by', 'options', 'instances']: monkeypatch_query_method(ctx, class_, name) for name in ['flush', 'delete', 'expire', 'refresh', 'expunge', 'merge', 'save', 'update', 'save_or_update']: monkeypatch_objectstore_method(ctx, class_, name) diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py index 2266f9fa8d..c29933ef93 100644 --- a/lib/sqlalchemy/orm/query.py +++ b/lib/sqlalchemy/orm/query.py @@ -828,15 +828,56 @@ class Query(object): return list(self) - def scalar(self): + def one(self): + """Return the first result of this ``Query``, raising an exception if more than one row exists. + + This results in an execution of the underlying query. + + this method is for forwards-compatibility with 0.4. + """ + + if self._col is None or self._func is None: + ret = list(self[0:2]) + + if len(ret) == 1: + return ret[0] + elif len(ret) == 0: + raise exceptions.InvalidRequestError('No rows returned for one()') + else: + raise exceptions.InvalidRequestError('Multiple rows returned for one()') + else: + return self._col_aggregate(self._col, self._func) + + def first(self): """Return the first result of this ``Query``. This results in an execution of the underlying query. + + this method is for forwards-compatibility with 0.4. """ + if self._col is None or self._func is None: - return self[0] + ret = list(self[0:1]) + if len(ret) > 0: + return ret[0] + else: + return None else: return self._col_aggregate(self._col, self._func) + + def all(self): + return self.list() + + def scalar(self): + """Return the first result of this ``Query``. + + This results in an execution of the underlying query. + + this method will be deprecated in 0.4; first() is added for + forwards-compatibility. + """ + + return self.first() def __iter__(self): return iter(self.select_whereclause()) diff --git a/test/orm/inheritance5.py b/test/orm/inheritance5.py index 56a83f5757..b0a905f339 100644 --- a/test/orm/inheritance5.py +++ b/test/orm/inheritance5.py @@ -843,9 +843,11 @@ class CustomPKTest(testbase.ORMTest): Column('id', Integer, primary_key=True), Column('type', String(30), nullable=False), Column('data', String(30))) + # note that the primary key column in t2 is named differently t2 = Table('t2', metadata, Column('t2id', Integer, ForeignKey('t1.id'), primary_key=True), Column('t2data', String(30))) + def test_custompk(self): """test that the primary_key attribute is propigated to the polymorphic mapper""" -- 2.47.2