On 3/31/07, Michael Bayer <[EMAIL PROTECTED]> wrote:

> On Mar 31, 2007, at 1:17 PM, Gaetan de Menten wrote:
>
> > That's approximately what I did in my patch with the new "params"
> > keyword argument, except I only implemented the "set" operation, not
> > the add operation on the params. Anyway, what can/should I do to get
> > this included? Do you have any advice/pointers on how to do the same
> > for eager attributes? (or will you implement it yourself?)
>
> im totally into a series of engine/execution patches/refactorings
> right now, so for properties that have "lazy=False", there is still a
> LazyLoader strategy there...you should just call
> property._get_strategy(LazyLoader) in all cases to get at it.

In case anybody is interested, here is my patch slightly modified with
what you suggest above. Now it works wonders for both lazy and eager
relationships. There is something ugly about it though: imports. I
have to import the LazyLoader class from the orm.strategies module,
but that module imports query, so what I did is import the LazyLoader
class inside the from_attr method to avoid a "circular import"
problem.

By the way, should I create a ticket for this?
-- 
Gaƫtan de Menten
http://openhex.org

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~----------~----~----~----~------~----~------~--~---

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__ = ['Query', 'QueryContext', 'SelectionContext']
 
 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]
 
         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]
+        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] = loader.parent.get_attr_by_column(instance, col)
+            if params[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:

Reply via email to