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
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.
# 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()
pass
db, dbapi = None, None
-class MockReconnectTest(TestBase):
+class MockReconnectTest(object):
def setUp(self):
global db, dbapi
dbapi = MockDBAPI()
assert len(dbapi.connections) == 1
engine = None
-class RealReconnectTest(TestBase):
+class RealReconnectTest(object):
def setUp(self):
global engine
engine = engines.reconnecting_engine()
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})
_sessions.clear()
_mapper_registry.clear()
-class MemUsageTest(EnsureZeroed):
+class MemUsageTest(object):
# ensure a pure growing test trips the assertion
@testing.fails_if(lambda:True)
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
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)})
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):