On 3/26/07, Michael Bayer <[EMAIL PROTECTED]> wrote:
>
> > (and whether that be a .query() or Query() or SelectResults not big
> > difference imo.)
> >
>
> i vote Query().

I tried to implement it but I couldn't do it the way I wanted to. The
problem is: how do I construct a clause from a clause with bind
parameters + a dictionary containing the values for said bind
parameters? I've only seen bind parameters resolved at execution time.
Is it possible to resolve them earlier? In the attached patch, I used
a workaround which is to store the bind parameters in the query
itself, and then use them whenever the query is executed.

Two remarks:

* I've implemented Query.from_attr, instead of adding new keywords to
the Query "constructor", because I think:

    Query.from_attr(someuser, 'addresses')

looks better, is shorter and is more readable than:

    Query('Address', instance=someuser, attr_name='addresses')

* It only works for lazy attributes. I don't think there is any reason
we couldn't make it work for eager attributes, but by looking at the
eagerloader code, I couldn't figure how to do it.

-- 
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 2444)
+++ orm/query.py        (working copy)
@@ -42,12 +42,32 @@
         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):
+        prop = instance.mapper.props[attr_name]
+        loader = prop.strategy
+        #TODO: make it work for eager loader too.
+        # code taken from strategies.py
+        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 +91,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):
@@ -690,8 +711,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