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?
The Session begins in a mostly stateless form. Once queries are issued or other objects are persisted with it, it requests a connection resource from an Engine that is associated with the Session , and then establishes a transaction on that connection.
session. flush() communicates a series of operations to the database (insert, update, delete). The database maintains them as pending operations in a transaction.
The Session. expire() and Session. refresh() methods are used in those cases when one wants to force an object to re-load its data from the database, in those cases when it is known that the current state of data is possibly stale.
SQLAlchemy is the ORM of choice for working with relational databases in python. The reason why SQLAlchemy is so popular is because it is very simple to implement, helps you develop your code quicker and doesn't require knowledge of SQL to get started.
You can use middleware
Example.
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)
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()
Register middleware.
import falcon
app = falcon.API(middleware=[
SQLAlchemySessionManager(Session),
])
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()
There is a package on pypi, falcon-sqla, that provides a middleware to manage SQLAlchemy sessions with Falcon.
It uses the request context object to add a different session to each http request, avoiding the need to use a scoped session.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With