'children':relation(MyOtherClass, lazy=None)
})
-* To load child objects, just use a query:
+* To load child objects, just use a query. Of particular convenience is that `Query` is a generative object, so you can return
+it as is, allowing additional criterion to be added as needed:
{python}
class Organization(object):
def __init__(self, name):
self.name = name
- def find_members(self, criterion):
- """locate a subset of the members associated with this Organization"""
- return object_session(self).query(Member).select(and_(member_table.c.name.like(criterion), org_table.c.org_id==self.org_id), from_obj=[org_table.join(member_table)])
-
+ member_query = property(lambda self: object_session(self).query(Member).with_parent(self))
+
+ myorg = sess.query(Organization).get(5)
+
+ # get all members
+ members = myorg.member_query.list()
+
+ # query a subset of members using LIMIT/OFFSET
+ members = myorg.member_query[5:10]
+
* Use `passive_deletes=True` to disable child object loading on a DELETE operation, in conjunction with "ON DELETE (CASCADE|SET NULL)" on your database to automatically cascade deletes to child objects. Note that "ON DELETE" is not supported on SQLite, and requires `InnoDB` tables when using MySQL:
{python}
The `join()` method is an easier-to-use version of the `join_by()`, `join_to()` and `join_via()` methods, all of which produce `ClauseElements` that can be constructed into a query criterion. Consult the generated documentation for information on these methods.
+#### Joining from a Parent Object {@name=joinparent}
+
+(new in 0.3.7) To help in navigating collections, the `with_parent()` generative method adds join criterion which corresponds to instances which belong to a particular parent. This method makes use of the same "lazy loading" criterion used to load relationships normally, which means it also works seamlessly for self-referential relationships. For example, to load all the `Address` objects which belong to a particular `User`:
+
+ {python}
+ # load a user
+ someuser = session.query(User).get(2)
+
+ # load the addresses of that user
+ addresses = session.query(Address).with_parent(someuser).list()
+
+ # filter the results
+ someaddresses = session.query(Address).with_parent(someuser).filter_by(email_address="foo@bar.com").list()
+
+
#### Eager Loading {@name=eagerload}
Eager Loading describes the loading of parent and child objects across a relation using a single query. The purpose of eager loading is strictly one of performance enhancement; eager loading has **no impact** on the results of a query, except that when traversing child objects within the results, lazy loaders will not need to issue separate queries to load those child objects.
class Organization(object):
def __init__(self, name):
self.name = name
- def find_members(self, criterion):
- """locate a subset of the members associated with this Organization"""
- return object_session(self).query(Member).select(and_(member_table.c.name.like(criterion), org_table.c.org_id==self.org_id), from_obj=[org_table.join(member_table)])
+ member_query = property(lambda self:object_session(self).query(Member).with_parent(self),
+ doc="""locate a subset of the members associated with this Organization""")
class Member(object):
def __init__(self, name):
# reload. load the org and some child members
print "-------------------------\nload subset of members"
org = sess.query(Organization).get(org.org_id)
-members = org.find_members('%member t%')
+members = org.member_query.filter_by(member_table.c.name.like('%member t%')).list()
print members
sess.clear()