[Zope-dev] Re: zope.sqlalchemy, integration ideas
Martijn Faassen
faassen at startifact.com
Fri May 30 08:32:05 EDT 2008
Hey Laurence,
[cc-ed Mike in case he hadn't seen this thread and has comments]
Thanks for the continued back and forth; I'm learning about SQLAlchemy
and hopefully my pushing helps you improve your ideas too.
Laurence Rowe wrote:
> Martijn Faassen wrote:
[using scoped sessions]
> That would be fine if you had the same configuration across all sessions
> (e.g. they all connected to the same engine / database) or each session
> was configured at the start of every request. Presumably we will want to
> connect different application instances to different databases.
Mike Bayer suggested configuring the session with the proper engine at
the start of each request in his example that I quote at the start of
the thread. How expensive actually is it to configure a session with an
engine? I'm still getting back to combining scoped sessions and
utilities, though.
We need to do two things:
* convince scoped session to return the session appropriate for our
application. We can do this by introducing a custom scopefunc that takes
application into account (by looking up a utility in it that knows what
scope the application has)
* convince the session factory to look up application specific
configuration information the first time a new scope is entered.
> This means that if we have a central register of ScopedSessions, then we
> must key it by some unique application id (path I guess).
> def application_session(app):
> try:
> return registry[app.getPath()]()
> except KeyError:
> return registry.setdefault(app.getPath(),
> scoped_session(sessionmaker(**app.getConfiguration())))()
I don't understand, why is a further registry necessary? What is wrong
with the modified scopefunc I suggested (using path or whatever you
prefer to key it)? Then you don't need a registry of ScopedSessions,
ScopedSession *is* that registry...
def our_scope_func():
return (component.getUtility(ISessionSiteScope).applicationScope(),
thread.getindent())
where applicationScope could be the path or the unique id or whatever
would be best for the application, as long as it's unique per app.
Then we also introduce a custom session factory that does a utility
lookup for its configuration (I'm handwaving hopefully non-essential
details here):
def our_session_factory():
config = component.getUtility(ISessionSiteScope).configuration()
return sessionmaker(**config)()
Session = scoped_session(our_session_factory, our_scope_func)
ScopedSession should then take care of the rest. ISessionSiteScope is
looked up each time you instantiate Session. 'configuration()' is only
called the *first* time you instantiate a session in a particular scope,
after that the configuration is cached.
> My point about using adapters, or indeed properties to access the
> session, is that the only object needing to access the session which
> cannot look it up directly with Session.object_session(object) is the
> application root object. To me it seems simpler to do this than to
> register utilities. Also it would be nice to have a consistent way to
> lookup the session.
I think we can agree that the ideal way to look up the session would be
to allow the following in applications, right?
from zope.rdbintegration import Session
session = Session()
and then session would always be an appropriately configured session for
the current scope. Now please explain to me why what I sketched out
above can't work. :)
(note that if you want two cooperating applications each using their own
session, you're required to use setSite() before you call into the
second application. This is required anyway to make other local utility
lookups work properly for that other application, so this is not an
extra burden on developers)
Regards,
Martijn
More information about the Zope-Dev
mailing list