On Thu, Jun 6, 2013 at 2:20 PM, Michael Bayer <mike...@zzzcomputing.com> wrote: > > diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py > index c2ec72c..b458975 100644 > --- a/lib/sqlalchemy/orm/query.py > +++ b/lib/sqlalchemy/orm/query.py > @@ -40,12 +40,15 @@ from ..sql import ( > __all__ = ['Query', 'QueryContext', 'aliased'] > > > -def _generative(*assertions): > +def _generative(*assertions, maintain_baked=False): > """Mark a method as generative.""" > > @util.decorator > def generate(fn, *args, **kw): > self = args[0]._clone() > + if not maintain_baked: > + del self._baked_cache > + del self._baked_context > for assertion in assertions: > assertion(self, fn.func_name) > fn(self, *args[1:], **kw) > @@ -1157,7 +1160,7 @@ class Query(object): > > self._lockmode = mode > > - @_generative() > + @_generative(maintain_baked=True) > def params(self, *args, **kwargs): > """add values for bind parameters which may have been > specified in filter().
That doesn't seem to be enough. subqueryload seems to be using the wrong query still, after clearing the baked context, resulting in some very wrong sharing of connections between threads (I'm getting some very fun segmentation faults). I think it's with_parent, it clears the baked context through a filter, but the filter is called on the wrong query (the global query instance I use as template), that has the wrong session attached or something. This is my current BakedQuery: class BakedQuery(sqlalchemy.orm.query.Query): _baked_context = None _baked_cache = None def _clone(self): rv = super(BakedQuery, self)._clone() try: del rv._baked_context del rv._baked_cache except AttributeError: pass return rv def params(self, *p, **kw): rv = super(BakedQuery, self).params(*p, **kw) rv._baked_context = self._baked_context rv._baked_cache = self._baked_cache return rv def with_session(self, *p, **kw): rv = super(BakedQuery, self).with_session(*p, **kw) rv._baked_context = self._baked_context rv._baked_cache = self._baked_cache return rv @sqlalchemy.orm.query._generative() def bake_as(self, name, cache): """Freeze the statement used by this Query.""" if name not in cache: cache[name] = context = self._compile_context() del context.session del context.query self._baked_context = cache[name] self._baked_cache = cache def _compile_context(self, **kw): if self._baked_context is not None: QueryContext = sqlalchemy.orm.query.QueryContext context = QueryContext.__new__(QueryContext) context.__dict__.update(self._baked_context.__dict__) context.query = self context.session = self.session # need to fix these names, urg context.attributes = context._attributes = context.attributes.copy() return context else: return super(BakedQuery, self)._compile_context(**kw) def _execute_and_instances(self, querycontext): if self._baked_cache is not None: self = self.execution_options(compiled_cache=self._baked_cache) return super(BakedQuery, self)._execute_and_instances(querycontext) And I invoke it like: def some_function(query = blabla.bake_as(blablah)): return query.with_session(S).params(...).first() This code still breaks if I don't use a baked template: def some_function(query = blabla): return query.with_session(S).bake_as(blablah).params(...).first() -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at http://groups.google.com/group/sqlalchemy?hl=en. For more options, visit https://groups.google.com/groups/opt_out.