Skip to content

Instantly share code, notes, and snippets.

@kgriffs
Created November 18, 2014 18:49
Show Gist options
  • Save kgriffs/b4eb14c91212f2fa3a0a to your computer and use it in GitHub Desktop.
Save kgriffs/b4eb14c91212f2fa3a0a to your computer and use it in GitHub Desktop.
SQLAlchemySessionManager (B)
# =========================================================================
# middleware.py
# =========================================================================
import sqlalchemy.orm.scoping as scoping
class SQLAlchemySessionManager(object):
def __init__(self, session_factory, auto_commit=False):
self._session_factory = session_factory
self._scoped = isinstance(session_factory, scoping.ScopedSession)
self._auto_commit = auto_commit
def process_request(self, req, resp, params):
req.context['session'] = self._session_factory()
def process_response(self, req, resp):
session = req.context['session']
if self._auto_commit:
session.commit()
if self._scoped:
session.remove()
else:
session.close()
# =========================================================================
# db.py
# =========================================================================
import sqlalchemy.orm as orm
Session = orm.scoped_session(orm.sessionmaker())
# =========================================================================
# app.py
# =========================================================================
import falcon
import sqlalchemy as sa
import db
import middleware
# TODO: Load engine options from a config file
engine = sa.create_engine('postgresql://scott:tiger@localhost/')
db.Session.configure(bind=engine)
session_manager = middleware.SQLAlchemySessionManager(db.Session)
api = falcon.API(middleware=[session_manager])
# Alternatively, you could use the global hooks mechanism, but that is
# deprecated so will probably go away eventually (we need to sort out how
# to keep talons compatible with the latest falcon when that happens)
api_alt = falcon.API(before=[session_manager.process_request],
after=[session_manager.process_response])
# =========================================================================
# somewhere_else.py
# =========================================================================
import db
class Foo(object):
def do_something():
# Get the scoped session object (from thread-local storage)
session = db.Session()
# <use the session>
@rmrio
Copy link

rmrio commented Jul 14, 2015

Hi!
The example doesnt work properly, I get a failure containing the following traceback:

Traceback (most recent call last):
     File "/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/lib/python2.7/wsgiref/handlers.py", line 85, in run
    self.result = application(self.environ, self.start_response)
  File "/Users/me/Code/ipam/.venv/src/falcon-master/falcon/api.py", line 183, in __call__
    self._call_resp_mw(middleware_stack, req, resp, resource)
  File "/Users/me/Code/ipam/.venv/src/falcon-master/falcon/api.py", line 555, in _call_resp_mw
    process_response(req, resp, resource)
  File "/Users/me/Code/ipam/ipam/middleware.py", line 25, in process_response
    session.remove()
AttributeError: 'Session' object has no attribute 'remove'

The type of req.context['session'] is 'sqlalchemy.orm.session.Session'.
The line 14 should be:

        req.context['session'] = self._session_factory

?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment