Added query_cls= override to scoped_session's query_property

This commit is contained in:
Jason Kirtland
2008-09-27 01:37:26 +00:00
parent a32c1a1e25
commit 29a6af6d46
5 changed files with 32 additions and 9 deletions
+4 -1
View File
@@ -21,7 +21,10 @@ CHANGES
upon reentrant mapper compile() calls, something that
occurs when using declarative constructs inside of
ForeignKey objects.
- ScopedSession.query_property now accepts a query_cls factory,
overriding the session's configured query_cls.
- sql
- column.in_(someselect) can now be used as
a columns-clause expression without the subquery
+16 -3
View File
@@ -77,7 +77,7 @@ class ScopedSession(object):
self.session_factory.configure(**kwargs)
def query_property(self):
def query_property(self, query_cls=None):
"""return a class property which produces a `Query` object against the
class when called.
@@ -90,13 +90,26 @@ class ScopedSession(object):
# after mappers are defined
result = MyClass.query.filter(MyClass.name=='foo').all()
"""
Produces instances of the session's configured query class by
default. To override and use a custom implementation, provide
a ``query_cls`` callable. The callable will be invoked with
the class's mapper as a positional argument and a session
keyword argument.
There is no limit to the number of query properties placed on
a class.
"""
class query(object):
def __get__(s, instance, owner):
mapper = class_mapper(owner, raiseerror=False)
if mapper:
return self.registry().query(mapper)
if query_cls:
# custom query class
return query_cls(mapper, session=self.registry())
else:
# session's configured query class
return self.registry().query(mapper)
else:
return None
return query()
+3 -3
View File
@@ -46,7 +46,7 @@ class MockCursor(object):
pass
db, dbapi = None, None
class MockReconnectTest(TestBase):
class MockReconnectTest(object):
def setUp(self):
global db, dbapi
dbapi = MockDBAPI()
@@ -175,7 +175,7 @@ class MockReconnectTest(TestBase):
assert len(dbapi.connections) == 1
engine = None
class RealReconnectTest(TestBase):
class RealReconnectTest(object):
def setUp(self):
global engine
engine = engines.reconnecting_engine()
@@ -281,7 +281,7 @@ class RealReconnectTest(TestBase):
self.assertEquals(conn.execute(select([1])).scalar(), 1)
assert not conn.invalidated
class RecycleTest(TestBase):
class RecycleTest(object):
def test_basic(self):
for threadlocal in (False, True):
engine = engines.reconnecting_engine(options={'pool_recycle':1, 'pool_threadlocal':threadlocal})
+1 -1
View File
@@ -54,7 +54,7 @@ class EnsureZeroed(_base.ORMTest):
_sessions.clear()
_mapper_registry.clear()
class MemUsageTest(EnsureZeroed):
class MemUsageTest(object):
# ensure a pure growing test trips the assertion
@testing.fails_if(lambda:True)
+8 -1
View File
@@ -2,7 +2,7 @@ import testenv; testenv.configure_for_tests()
from testlib import sa, testing
from sqlalchemy.orm import scoped_session
from testlib.sa import Table, Column, Integer, String, ForeignKey
from testlib.sa.orm import mapper, relation
from testlib.sa.orm import mapper, relation, query
from testlib.testing import eq_
from orm import _base
@@ -38,10 +38,14 @@ class ScopedSessionTest(_base.MappedTest):
def test_basic(self):
Session = scoped_session(sa.orm.sessionmaker())
class CustomQuery(query.Query):
pass
class SomeObject(_base.ComparableEntity):
query = Session.query_property()
class SomeOtherObject(_base.ComparableEntity):
query = Session.query_property()
custom_query = Session.query_property(query_cls=CustomQuery)
mapper(SomeObject, table1, properties={
'options':relation(SomeOtherObject)})
@@ -62,6 +66,9 @@ class ScopedSessionTest(_base.MappedTest):
eq_(SomeOtherObject(someid=1),
SomeOtherObject.query.filter(
SomeOtherObject.someid == sso.someid).one())
assert isinstance(SomeOtherObject.query, query.Query)
assert not isinstance(SomeOtherObject.query, CustomQuery)
assert isinstance(SomeOtherObject.custom_query, query.Query)
class ScopedMapperTest(_ScopedTest):