import sqlalchemy import cherrypy from cherrypy.process import plugins from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() def db(): return cherrypy.request.db class SAEnginePlugin(plugins.SimplePlugin): def __init__(self, bus, dbcon): plugins.SimplePlugin.__init__(self, bus) self.sa_engine = dbcon self.bus.subscribe("bind", self.bind) def start(self): Base.metadata.create_all(self.sa_engine) def bind(self, session): session.configure(bind=self.sa_engine) class SATool(cherrypy.Tool): def __init__(self): cherrypy.Tool.__init__(self, 'before_request_body', self.bind_session, priority=100) self.session = sqlalchemy.orm.scoped_session( sqlalchemy.orm.sessionmaker(autoflush=True, autocommit=False)) def _setup(self): cherrypy.Tool._setup(self) cherrypy.request.hooks.attach('on_end_resource', self.commit_transaction, priority=80) def bind_session(self): cherrypy.engine.publish('bind', self.session) cherrypy.request.db = self.session con = cherrypy.request.db.connection().connection.connection if hasattr(con, "ping"): # not available on sqlite con.ping() def commit_transaction(self): cherrypy.request.db = None try: self.session.commit() except Exception: self.session.rollback() raise finally: self.session.remove()