- further fixes to sqlite booleans, weren't working as defaults
- fix to postgres sequence quoting when using schemas
- fixed direct execution of Compiled objects
+- fixed bug where eagerload() (nor lazyload()) option didn't properly
+instruct the Query whether or not to use "nesting" when producing a
+LIMIT query.
0.3.0
- General:
# "polymorphic identity" of the row, which indicates which Mapper should be used
# to construct a new object instance from that row.
self.polymorphic_on = polymorphic_on
+ self._eager_loaders = util.Set()
# our 'polymorphic identity', a string name that when located in a result set row
# indicates this Mapper should be used to construct the object instance for that row.
def has_eager(self):
"""return True if one of the properties attached to this Mapper is eager loading"""
- return getattr(self, '_has_eager', False)
+ return len(self._eager_loaders) > 0
def instances(self, cursor, session, *mappers, **kwargs):
"""return a list of mapped instances corresponding to the rows in a given ResultProxy."""
generated query as a subquery inside of a larger eager-loading query. this is used
with keywords like distinct, limit and offset and the mapper defines eager loads."""
return (
- self.mapper.has_eager()
+ len(querycontext.eager_loaders) > 0
and self._nestable(**querycontext.select_args())
)
self.distinct = kwargs.pop('distinct', False)
self.limit = kwargs.pop('limit', None)
self.offset = kwargs.pop('offset', None)
+ self.eager_loaders = util.Set([x for x in query.mapper._eager_loaders])
self.statement = None
super(QueryContext, self).__init__(query.mapper, query.with_options, **kwargs)
def select_args(self):
super(EagerLoader, self).init()
if self.parent.isa(self.mapper):
raise exceptions.ArgumentError("Error creating eager relationship '%s' on parent class '%s' to child class '%s': Cant use eager loading on a self referential relationship." % (self.key, repr(self.parent.class_), repr(self.mapper.class_)))
- self.parent._has_eager = True
+ self.parent._eager_loaders.add(self.parent_property)
self.clauses = {}
self.clauses_by_lead_mapper = {}
def __init__(self, key, lazy=True):
super(EagerLazyOption, self).__init__(key)
self.lazy = lazy
+ def process_query_property(self, context, prop):
+ if self.lazy:
+ if prop in context.eager_loaders:
+ context.eager_loaders.remove(prop)
+ else:
+ context.eager_loaders.add(prop)
+ super(EagerLazyOption, self).process_query_property(context, prop)
def get_strategy_class(self):
if self.lazy:
return LazyLoader
self.assert_result(l, User, *user_address_result)
self.assert_sql_count(db, go, 0)
+ def testeageroptionswithlimit(self):
+ sess = create_session()
+ mapper(User, users, properties = dict(
+ addresses = relation(mapper(Address, addresses), lazy = True)
+ ))
+ u = sess.query(User).options(eagerload('addresses')).get_by(user_id=8)
+
+ def go():
+ assert u.user_id == 8
+ assert len(u.addresses) == 3
+ self.assert_sql_count(db, go, 0)
+
+ def testlazyoptionswithlimit(self):
+ sess = create_session()
+ mapper(User, users, properties = dict(
+ addresses = relation(mapper(Address, addresses), lazy = False)
+ ))
+ u = sess.query(User).options(lazyload('addresses')).get_by(user_id=8)
+
+ def go():
+ assert u.user_id == 8
+ assert len(u.addresses) == 3
+ self.assert_sql_count(db, go, 1)
+
def testeagerdegrade(self):
"""tests that an eager relation automatically degrades to a lazy relation if eager columns are not available"""
sess = create_session()