[Zope-dev] Re: SQLAlchemy (zope.sqlalchemy) integration

Hermann Himmelbauer dusty at qwer.tk
Fri Jun 6 05:30:01 EDT 2008


Am Donnerstag, 5. Juni 2008 19:38 schrieb Laurence Rowe:
> Hermann Himmelbauer wrote:
> > Am Mittwoch, 4. Juni 2008 22:09 schrieb Laurence Rowe:
> >> Hermann Himmelbauer wrote:
> >>> In my application, I then use getSASession() to retrieve my session.
> >>>
> >>> However, what I think is not that beautiful is the "s.bind = engine"
> >>> part. Are there any suggestions how to improve this?
> >>
> >> You have two options
> >>
> >> If you ever need to mix objects from different `sites` into the same
> >> session, you should use an adapter on your root object like:
> >>
> >> If you don't need to mix objects from different `sites` then you can
> >> register a local utility for ISessionConfig.
> >>
> >> def scope():
> >>    return getUtility(ISessionConfig).uid, thread.get_ident()
> >>
> >> def factory():
> >>    engine = Engine(getUtility(ISessionConfig).url)
> >>    return create_session(
> >>      transactional=True, autoflush=True, bind=engine
> >>      extension=ZopeTransactionExtension(),
> >>      ))
> >>
> >> Session = scoped_session(factory, scopefunc=scope)
> >>
> >> Then you can just import Session and use:
> >>     session = Session()
> >
> > Ok, great, thanks for help. The only thing I don't understand is what
> > "uid" from the SessionConfig utility is. Below is my full database
> > integration code which works for me, perhaps this is helpful to someone
> > else.
>
> uid is some id that distinguishes your various application instances. On
> zope 2 I would probably use getPhysicalPath(). I don't know what the
> zope3 equivalent is.

Hmmm, maybe it's:

from zope.traversing.api import getPath
from zope.app.component.hooks import getSite
@property
def uid(self):
    return getPath(getSite())

> Looking at your code, why did you decide to store the engine on a _v_
> attribute? I don't think you need to save it at all. You can access a
> connection through session.connection()

Ok, but in case I create the engine in the session_factor, e.g.:

def session_factory():
    engine = createEngine(....)
    return create_session(transactional = True,
                          autoflush = True,
                          bind = engine,
                          extension = ZopeTransactionExtension())

Wouldn't the engine be created for every request, as the scope changes and the 
factory is called? In my case, the engine is created when the first session 
is fetched. After that it will be recreated only if the DSN changes.

> > Btw., I'd suggest to put such code / session use cases in some Zope
> > package, maybe into zope.sqlalchemy, or e.g. zope.sqlalchemy_utility as
> > it's really difficult for non-insiders to set this up.
>
> We would need to work out what parts are useful to the various higher
> level sqlalchemy / zope packages. Once we can agree on a common core
> then we should at least make simple use cases available through
> zope.sqlalchemy directly.

In my scenario, all I need is a local utility. This is something that was 
available in z3c.zalchemy, too (and I think also in z3c.sqlalchemy).
The problem about putting this code into zope.sqlalchemy is that the 
local-utility code may be based on other zope packages and hence create 
unwanted dependencies. But I'm unsure about this.

Best Regards,
Hermann

-- 
hermann at qwer.tk
GPG key ID: 299893C7 (on keyservers)
FP: 0124 2584 8809 EF2A DBF9  4902 64B4 D16B 2998 93C7


More information about the Zope-Dev mailing list