pythonsqlalchemyflask-sqlalchemyfalconframework

SQLAlchemy and Falcon - session initialization


I'm wondering where the best place would be to create a scoped session for use in falcon.

From reading the flask-sqlalchemy code, it, in a round about way, does something like this:

from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker

try:
    from greenlet import get_current as get_ident
except ImportError:
    try:
        from thread import get_ident
    except ImportError:
        from _thread import get_ident

connection_uri = 'postgresql://postgres:@localhost:5432/db'
engine = create_engine(connection_uri)
session_factory = sessionmaker(bind=engine)
session_cls = scoped_session(session_factory, scopefunc=get_ident)
session = session_cls()

Would this work for falcon? Will the get_ident func "do the right thing" when using gunicorn?


Solution

  • You can use middleware

    Example.

    1. Create engine, session_factory and scoped_session object.

      from sqlalchemy import create_engine
      from sqlalchemy.orm import scoped_session
      from sqlalchemy.orm import sessionmaker
      
      import settings
      
      
      engine = create_engine(
          '{engine}://{username}:{password}@{host}:{port}/{db_name}'.format(
          **settings.POSTGRESQL
          )
      )
      
      session_factory = sessionmaker(bind=engine)
      Session = scoped_session(session_factory)
      
    2. Create middleware.

      class SQLAlchemySessionManager:
          """
          Create a scoped session for every request and close it when the request
          ends.
          """
      
          def __init__(self, Session):
              self.Session = Session
      
          def process_resource(self, req, resp, resource, params):
              resource.session = self.Session()
      
          def process_response(self, req, resp, resource, req_succeeded):
              if hasattr(resource, 'session'):
                  Session.remove()
      
    3. Register middleware.

      import falcon
      
      
      app = falcon.API(middleware=[
          SQLAlchemySessionManager(Session),
      ])
      
    4. Session is accessible in every request.

      import falcon
      
      
      class MyAPI:
      
          def on_get(self, req, resp):
              # You can access self.session here
              # self.session.add(foo)
              # self.session.commit()