From: Mike Bayer Date: Sun, 9 Mar 2008 22:51:55 +0000 (+0000) Subject: - dynamic_loader() / lazy="dynamic" now accepts and uses X-Git-Tag: rel_0_4_4~18 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4bd956b50f3c6c1c99592daff6427f8715da3f6c;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - dynamic_loader() / lazy="dynamic" now accepts and uses the order_by parameter in the same way in which it works with relation(). --- diff --git a/CHANGES b/CHANGES index b176db4ac9..32355b56ee 100644 --- a/CHANGES +++ b/CHANGES @@ -226,7 +226,11 @@ CHANGES - The proper error message is raised when trying to access expired instance attributes with no session present - + + - dynamic_loader() / lazy="dynamic" now accepts and uses + the order_by parameter in the same way in which it works + with relation(). + - Added expire_all() method to Session. Calls expire() for all persistent instances. This is handy in conjunction with... diff --git a/lib/sqlalchemy/orm/__init__.py b/lib/sqlalchemy/orm/__init__.py index eb92988ff7..46c81952f8 100644 --- a/lib/sqlalchemy/orm/__init__.py +++ b/lib/sqlalchemy/orm/__init__.py @@ -274,7 +274,7 @@ def relation(argument, secondary=None, **kwargs): def dynamic_loader(argument, secondary=None, primaryjoin=None, secondaryjoin=None, entity_name=None, foreign_keys=None, backref=None, post_update=False, cascade=None, remote_side=None, enable_typechecks=True, - passive_deletes=False): + passive_deletes=False, order_by=None): """construct a dynamically-loading mapper property. This property is similar to relation(), except read operations @@ -292,7 +292,7 @@ def dynamic_loader(argument, secondary=None, primaryjoin=None, secondaryjoin=Non return PropertyLoader(argument, secondary=secondary, primaryjoin=primaryjoin, secondaryjoin=secondaryjoin, entity_name=entity_name, foreign_keys=foreign_keys, backref=backref, post_update=post_update, cascade=cascade, remote_side=remote_side, enable_typechecks=enable_typechecks, - passive_deletes=passive_deletes, + passive_deletes=passive_deletes, order_by=order_by, strategy_class=DynaLoader) #def _relation_loader(mapper, secondary=None, primaryjoin=None, secondaryjoin=None, lazy=True, **kwargs): diff --git a/lib/sqlalchemy/orm/dynamic.py b/lib/sqlalchemy/orm/dynamic.py index 98702ecb04..0d72beddb6 100644 --- a/lib/sqlalchemy/orm/dynamic.py +++ b/lib/sqlalchemy/orm/dynamic.py @@ -7,9 +7,10 @@ from sqlalchemy.orm.query import Query from sqlalchemy.orm.mapper import has_identity, object_mapper class DynamicAttributeImpl(attributes.AttributeImpl): - def __init__(self, class_, key, typecallable, target_mapper, **kwargs): + def __init__(self, class_, key, typecallable, target_mapper, order_by, **kwargs): super(DynamicAttributeImpl, self).__init__(class_, key, typecallable, **kwargs) self.target_mapper = target_mapper + self.order_by=order_by def get(self, state, passive=False): if passive: @@ -130,7 +131,10 @@ class AppenderQuery(Query): except exceptions.InvalidRequestError: raise exceptions.UnboundExecutionError("Parent instance %s is not bound to a Session, and no contextual session is established; lazy load operation of attribute '%s' cannot proceed" % (mapperutil.instance_str(instance), self.attr.key)) - return sess.query(self.attr.target_mapper).with_parent(instance, self.attr.key) + q = sess.query(self.attr.target_mapper).with_parent(instance, self.attr.key) + if self.attr.order_by: + q = q.order_by(self.attr.order_by) + return q def assign(self, collection): instance = self.instance diff --git a/lib/sqlalchemy/orm/strategies.py b/lib/sqlalchemy/orm/strategies.py index 81a5895f49..a7ab3d0056 100644 --- a/lib/sqlalchemy/orm/strategies.py +++ b/lib/sqlalchemy/orm/strategies.py @@ -240,7 +240,7 @@ class AbstractRelationLoader(LoaderStrategy): class DynaLoader(AbstractRelationLoader): def init_class_attribute(self): self.is_class_level = True - self._register_attribute(self.parent.class_, dynamic=True, target_mapper=self.parent_property.mapper) + self._register_attribute(self.parent.class_, dynamic=True, target_mapper=self.parent_property.mapper, order_by=self.parent_property.order_by) def create_row_processor(self, selectcontext, mapper, row): return (None, None, None) diff --git a/test/orm/dynamic.py b/test/orm/dynamic.py index c85d841073..ae8ef4e5ea 100644 --- a/test/orm/dynamic.py +++ b/test/orm/dynamic.py @@ -31,6 +31,14 @@ class DynamicTest(FixtureTest): sess = create_session() u = sess.query(User).get(8) self.assertEquals(list(u.addresses.order_by(desc(Address.email_address))), [Address(email_address=u'ed@wood.com'), Address(email_address=u'ed@lala.com'), Address(email_address=u'ed@bettyboop.com')]) + + def test_configured_order_by(self): + mapper(User, users, properties={ + 'addresses':dynamic_loader(mapper(Address, addresses), order_by=desc(Address.email_address)) + }) + sess = create_session() + u = sess.query(User).get(8) + self.assertEquals(list(u.addresses), [Address(email_address=u'ed@wood.com'), Address(email_address=u'ed@lala.com'), Address(email_address=u'ed@bettyboop.com')]) def test_count(self): mapper(User, users, properties={