From: Mike Bayer Date: Fri, 25 Jan 2008 18:16:12 +0000 (+0000) Subject: - added standalone "query" class attribute generated X-Git-Tag: rel_0_4_3~70 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=33a6724e33140861fbd66de61875797408a1e02e;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - added standalone "query" class attribute generated by a scoped_session. This provides MyClass.query without using Session.mapper. Use via: MyClass.query = Session.query_property() --- diff --git a/CHANGES b/CHANGES index 4f1d422c06..e39f891a45 100644 --- a/CHANGES +++ b/CHANGES @@ -32,6 +32,12 @@ CHANGES works fully for all embedded selectables. - orm + - added standalone "query" class attribute generated + by a scoped_session. This provides MyClass.query + without using Session.mapper. Use via: + + MyClass.query = Session.query_property() + - The proper error message is raised when trying to access expired instance attributes with no session present diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py index 07075efd09..d9dc70a585 100644 --- a/lib/sqlalchemy/orm/mapper.py +++ b/lib/sqlalchemy/orm/mapper.py @@ -1578,7 +1578,7 @@ def object_mapper(object, entity_name=None, raiseerror=True): return None return mapper -def class_mapper(class_, entity_name=None, compile=True): +def class_mapper(class_, entity_name=None, compile=True, raiseerror=True): """Given a class and optional entity_name, return the primary Mapper associated with the key. If no mapper can be located, raises ``InvalidRequestError``. @@ -1587,7 +1587,10 @@ def class_mapper(class_, entity_name=None, compile=True): try: mapper = class_._class_state.mappers[entity_name] except (KeyError, AttributeError): - raise exceptions.InvalidRequestError("Class '%s' entity name '%s' has no mapper associated with it" % (class_.__name__, entity_name)) + if raiseerror: + raise exceptions.InvalidRequestError("Class '%s' entity name '%s' has no mapper associated with it" % (class_.__name__, entity_name)) + else: + return None if compile: return mapper.compile() else: diff --git a/lib/sqlalchemy/orm/scoping.py b/lib/sqlalchemy/orm/scoping.py index 19cd44884c..479b2f7374 100644 --- a/lib/sqlalchemy/orm/scoping.py +++ b/lib/sqlalchemy/orm/scoping.py @@ -1,5 +1,5 @@ from sqlalchemy.util import ScopedRegistry, to_list, get_cls_kwargs -from sqlalchemy.orm import MapperExtension, EXT_CONTINUE, object_session +from sqlalchemy.orm import MapperExtension, EXT_CONTINUE, object_session, class_mapper from sqlalchemy.orm.session import Session from sqlalchemy import exceptions import types @@ -69,6 +69,30 @@ class ScopedSession(object): self.session_factory.configure(**kwargs) + def query_property(self): + """return a class property which produces a `Query` object against the + class when called. + + e.g.:: + Session = scoped_session(sessionmaker()) + + class MyClass(object): + query = Session.query_property() + + # after mappers are defined + result = MyClass.query.filter(MyClass.name=='foo').all() + + """ + + class query(object): + def __get__(s, instance, owner): + mapper = class_mapper(owner, raiseerror=False) + if mapper: + return self.registry().query(mapper) + else: + return None + return query() + def instrument(name): def do(self, *args, **kwargs): return getattr(self.registry(), name)(*args, **kwargs) diff --git a/test/orm/session.py b/test/orm/session.py index 930efe07ac..0a38198ac2 100644 --- a/test/orm/session.py +++ b/test/orm/session.py @@ -946,8 +946,10 @@ class ScopedSessionTest(ORMTest): def test_basic(self): Session = scoped_session(sessionmaker()) - class SomeObject(fixtures.Base):pass - class SomeOtherObject(fixtures.Base):pass + class SomeObject(fixtures.Base): + query = Session.query_property() + class SomeOtherObject(fixtures.Base): + query = Session.query_property() mapper(SomeObject, table, properties={ 'options':relation(SomeOtherObject) @@ -961,8 +963,9 @@ class ScopedSessionTest(ORMTest): Session.commit() Session.remove() - assert SomeObject(id=1, data="hello", options=[SomeOtherObject(someid=1)]) == Session.query(SomeObject).one() - + self.assertEquals(SomeObject(id=1, data="hello", options=[SomeOtherObject(someid=1)]), Session.query(SomeObject).one()) + self.assertEquals(SomeObject(id=1, data="hello", options=[SomeOtherObject(someid=1)]), SomeObject.query.one()) + self.assertEquals(SomeOtherObject(someid=1), SomeOtherObject.query.filter(SomeOtherObject.someid==sso.someid).one()) class ScopedMapperTest(PersistTest): def setUpAll(self):