On Feb 12, 2006, at 4:48 PM, Michael Bayer wrote:
Well, I was pursuing this differently. While I am moving in the same direction where UnitOfWork is not really dealt with publically, I have the Session's main purpose as managing the "scope" of a set of unit of works, such as thread-local, per- application, or custom.

May I respectfully disagree...I don't think the session should be managing scope. The session is the object that should be managed in a given "scope". If you really want to make the session manage the scope, then it should be a singleton (which is basically what the original objectstore was--a module, not a class). Otherwise we're talking about nested scopes, which gets very complicated to understand (and hard to debug). I don't think that is as useful as keeping it simple with a single UnitOfWork per session by default (well, not quite since the begin/commit thing will create additional "units of work").

that way someone can define some other algorithm for managing the scope of unitofwork, and install it as the "global" algorithm, or also "push" and "pop" the Session object into the current scope so that their algorithm can take effect just for certain blocks of code....

This can easily be implemented with the Session from my patch yesterday. Just extend it like this:

<code>

class ScopedSession(sqlalchemy.objectstore.Session):

    def __init__(self, hash_key=None, scope="application"):
        self._registry = util.ScopedRegistry(UnitOfWork, scope)
        super(ScopedSession, self).__init__(hash_key=hash_key)

    def _get_uow(self):
        return self._registry()

    def _set_uow(self, uow):
        if uow is None:
            self._registry.clear()
        else:
            self._registry.set(uow)

    uow = property(_get_uow, _set_uow)

</code>

I'm not sure why anyone would want to do this...it would be better to leave this as a possibility, but keep the default implementation simple since most people will not need this extra flexibility anyway.

such as, you might define a function that returns an ID for the currently focused window in your application.

This is brittle and bound to break as an application grows. I went down that road with the app I'm currently working on and it gets really messy really quickly. The problem comes when two windows need to interact--only the one that's in focus can run any data access code because the other one would be operating in the wrong session (or unitofwork or whatever scoped object).

I have put up preliminary docs for this on the site so you can see what I was getting at....but its not a final decision or anything like that, its just further along than this particular patch. it is more complicated but i think its a valuable function.

I do like the idea of removing "session" from the UnitOfWork and moving the "bind_to" operation totally within the Session, that way UnitOfWork doesnt need the parent "session". But if the Session is really going to manage the begin/commit thing, then the "parent" idea should come out of UnitOfWork too....UOW should just have "commit" which does the actual work, and thats it.

Sure. The Session could keep a stack of UnitOfWork instances. The top one is the active one. The depth can easily be checked with len (uow_stack). I had originally implemented it this way, but didn't see the need for the extra complexity. The parent thing still passed all tests, so I figured it was good enough.

perhaps Session could just set or otherwise associate attributes with the UnitOfWork so that UOW doesnt need to be aware of it. also, what do we gain by providing a "create a UnitOfWork" function ? I have that function too....but is there really some other way of constructing a single UnitOfWork someone might need ?

Probably not. Lets get rid of it (k.i.s.s.). If someone wants to use a custom UnitOfWork implementation they can extend Session in a similar way to the above example.


also, this patch removes the ability to "nest" begins/commits, having only the "outermost" begin/commit take effect, which is something people specifically asked for. they want to say:

        def foo():
                objectstore.begin()
                .. do stuff
                objectstore.commit()

and then have foo() callable inside a larger commit:

        objectstore.begin()
        foo()
        bar()
        objectstore.commit()

and have foo()'s transaction pulled upwards to the outermost transaction. you need a begin/commit counter to do that.

Hmm. Is there a test for that? I don't think my patch is causing it to fail.


anyway, I committed my most recent changes just now, so lets work from there...check out the docs to see how i was describing it. ive no issue with using get_session() instead of session(), and factoring out some of begin/commit into the session will be good if it simplifies UnitOfWork.


Good. As you might have noticed, I think it's important to keep the implementation as simple as possible. This will improve other developers' ability to understand how it works and to extend it when they need more flexibility. Make it do one thing well, don't try to be everything for everyone. Simple is better than complex...OK, I'll stop now...

~ Daniel



-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems?  Stop!  Download the new AJAX search engine that makes
searching your log files as easy as surfing the  web.  DOWNLOAD SPLUNK!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=103432&bid=230486&dat=121642
_______________________________________________
Sqlalchemy-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/sqlalchemy-users

Reply via email to