On Aug 18, 2008, at 5:08 AM, Alen Ribic wrote:

>
> sql.py
> ====================================
>
> class SQLAlchemyMiddleware(object):
>    """
>    Middleware for providing clean SQLAlchemy Session objects for each
> Request.
>    """
>    def __init__(self, application):
>        self.application = application
>        self.__engine = None
>
>    def get_engine(self):
>        if self.__engine is None:
>            self.__engine = create_engine(
>                settings.SQLALCHEMY_DEFAULT_URL,
>                pool_recycle=3600,
>                pool_size=20,
>                echo_pool=True
>            )
>        return self.__engine
>
>    def init_model(self, engine):
>        """Call before using any of the tables or classes in the
> model."""
>        sm = orm.sessionmaker(autoflush=True, transactional=True,
> bind=engine)
>
>        meta.engine = engine
>        meta.Session = orm.scoped_session(sm)
>
>    def __call__(self, environ, start_response):
>        try:
>            engine = self.get_engine()
>            self.init_model(engine)
>            return self.application(environ, start_response)
>        finally:
>            if meta.Session is not None:
>                meta.Session.remove()
>

The big mistake here is creating a brand new ScopedSession on each  
request.  This is not how ScopedSession was intended to be used; its  
created, like Engine, once per application.  Some details on this  
pattern are here:

http://www.sqlalchemy.org/docs/05/session.html#unitofwork_contextual_lifespan

The way you have it, a concurrent thread can easily interrupt the  
ScopedSession instance attached to "meta" and replace with a new one,  
with the old one being lost.

Here's a more reasonable approach:

class SQLAlchemyMiddleware(object):
    def __init__(self, application):
        self.application = application
        meta.engine = create_engine(
               settings.SQLALCHEMY_DEFAULT_URL,
               pool_recycle=3600,
               pool_size=20,
               echo_pool=True
           )
         meta.Session =  
orm.scoped_session(orm.sessionmaker(autoflush=True, transactional=True,
     bind=meta.engine))

    def __call__(self, environ, start_response):
        try:
            return self.application(environ, start_response)
        except:
            meta.Session.rollback()
            raise
        finally:
            meta.Session.remove()





--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to