- changed status to resolved
filtered one-to-many relationships
Issue #541
resolved
just want to make a ticket for the thread in http://groups.google.com/group/sqlalchemy/browse_thread/thread/bd5dae5167e8a3c4/a727d39f935d5016?lnk=gst&q=filtered&rnum=4#a727d39f935d5016 .
gaetans initial patch:
Index: orm/query.py
===================================================================
--- orm/query.py (revision 2493)
+++ orm/query.py (working copy)
@@ -8,6 +8,7 @@
from sqlalchemy.orm import mapper, class_mapper
from sqlalchemy.orm.interfaces import OperationContext, SynonymProperty
+
__all__ = ['QueryContext', 'SelectionContext']('Query',)
class Query(object):
@@ -42,12 +43,36 @@
self._distinct = kwargs.pop('distinct', False)
self._offset = kwargs.pop('offset', None)
self._limit = kwargs.pop('limit', None)
- self._criterion = None
+ self._criterion = kwargs.pop('criterion', None)
+ self._params = kwargs.pop('params', {})
self._joinpoint = self.mapper
self._from_obj = [self.table](self.table)
for opt in util.flatten_iterator(self.with_options):
opt.process_query(self)
+
+ def from_attr(cls, instance, attr_name):
+ from sqlalchemy.orm.strategies import LazyLoader
+
+ prop = instance.mapper.props[attr_name](attr_name)
+ loader = prop._get_strategy(LazyLoader)
+
+ # the following code is taken from strategies.py
+ # this gets the values of the columns referenced by the property
+ # for this specific instance
+ params = {}
+ allparams = True
+ for col, bind in loader.lazybinds.iteritems():
+ params[bind.key](bind.key) = loader.parent.get_attr_by_column(instance, col)
+ if params[bind.key](bind.key) is None:
+ allparams = False
+ break
+
+ if not allparams:
+ return None
+
+ return Query(prop.mapper, criterion=loader.lazywhere, params=params)
+ from_attr = classmethod(from_attr)
def _clone(self):
q = Query.__new__(Query)
@@ -71,6 +96,7 @@
q._from_obj = list(self._from_obj)
q._joinpoint = self._joinpoint
q._criterion = self._criterion
+ q._params = self._params
return q
def _get_session(self):
@@ -694,8 +720,10 @@
method, which takes the executed statement's ResultProxy
directly.
"""
-
- result = self.session.execute(self.mapper, clauseelement, params=params)
+ final_params = self._params.copy()
+ if params is not None:
+ final_params.update(params)
+ result = self.session.execute(self.mapper, clauseelement, params=final_params)
try:
return self.instances(result, **kwargs)
finally:
Comments (1)
-
reporter - Log in to comment
Ok, ive committed a refined version of the above patch, including a generative non-static version of the method (which I think is more useful), plus unit tests and some docs/examples which i think are handy, in changeset:2507 changeset:2508.