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: