it is possible to dig the stack to find the context u need... no worries about that, but u have to know the name of it, as there might be two contexts living in same scope (e.g.: copy data from DB1 to DB2), and u could get the wrong one -- python has no ordering in its namespaces/scopes/frames (a plain dict). There's another approach, organise yourself a stack and use that one, be it threadlocal or global or what. i have some working example at dbcook/misc/timed/util/stacks.py: http://dbcook.svn.sourceforge.net/viewvc/dbcook/trunk/dbcook/misc/timed/util/ and a maybe-working usage in dbcook/misc/timed/ timecontext.py + setup.py have a look svilen
On Thursday 03 July 2008 12:05:37 Iwan wrote: > Hi there, > > I have an idea I'd like to bounce off people here. It relates to > the problem described here: > http://www.sqlalchemy.org/docs/05/session.html#unitofwork_contextua >l > > The solution used there makes the assumption that each request will > happen in its own thread, and uses python's thread-local stuff to > do its magic. > > I was wondering if it is not possible to do something that is local > to the current call-stack, instead of the current thread. I think > there are two issues here: > a) a general mechanism for remembering a call-local context > b) using it to provide a call-local sqlalchemy session > > Now, I'm not sure yet how to do (b), but want to give an example of > (a) with a naive implementation to illustrate the idea. (Just note > this mechanism can be used for other important contextual info as > well, such as who the current user is, etc) > > With the following code, I can call a method b.bar, passing it some > "context" (which is not part of the method's original signature). > b.bar calls a.foo in turn, also not passing it anything, but inside > A.foo, the context can be retrieved from the call stack. The only > overhead incurred is during this last step, and I don't think it is > much. (Implementation of CC is at the bottom.) > > Any thoughts? > > class A(object): > def foo(self): > print CC.get_context() #CC here is assumed to be a > class, on which a class method is > # called to get > the current "context", which may be our session > # but I think > it can be used for more things than just the session > > class B(object): > a = A() > def bar(self, arg): > print arg > self.a.foo() > > b = B() > CC(b.bar, 'context stuff - a session or a dict?', 'some argument > for bar()') > > #--------------------- > # CC (should be before the examples above if you want to run it) > # > import inspect > > class CC(object): > def __init__(self, callable, context, *args, **kwargs): > self.callable = callable > self.context = context > self.callable(*args, **kwargs) > > @classmethod > def get_context(cls): > context = None > found = False > f = inspect.currentframe() > while not found and f.f_back: > theSelf = f.f_locals.get('self', None) > if theSelf.__class__ is cls: > context = theSelf.context > found = True > nextF = f.f_back > del f > f = nextF > > return context > > --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---