]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- added standalone "query" class attribute generated
authorMike Bayer <mike_mp@zzzcomputing.com>
Fri, 25 Jan 2008 18:16:12 +0000 (18:16 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Fri, 25 Jan 2008 18:16:12 +0000 (18:16 +0000)
by a scoped_session.  This provides MyClass.query
without using Session.mapper.  Use via:

MyClass.query = Session.query_property()

CHANGES
lib/sqlalchemy/orm/mapper.py
lib/sqlalchemy/orm/scoping.py
test/orm/session.py

diff --git a/CHANGES b/CHANGES
index 4f1d422c063a890ec528c49a52135d2475424193..e39f891a458a1b92944ad04b00145b2c85f03c94 100644 (file)
--- 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
 
index 07075efd09077aa11166ed95eb7a5fd87105f84a..d9dc70a5853d889b12d7f845ddc50fd31698c39d 100644 (file)
@@ -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:
index 19cd44884cf7f4840b728f491e7e03cda95d4333..479b2f7374983c6781edde74e4fad80db1e32db2 100644 (file)
@@ -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)
index 930efe07ac3e804036feb343696a98129e655b63..0a38198ac2eef8271435b9b787af4e78fe18f3e1 100644 (file)
@@ -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):