SQLAlchemy和Falcon - 会话初始化

14

我想知道在falcon中创建范围会话的最佳位置在哪里。

从阅读flask-sqlalchemy代码,它以一种迂回的方式做了类似于这样的事情:

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()

这对falcon可行吗?在使用gunicorn时,get_ident函数会“做正确的事情”吗?

2个回答

21

您可以使用中间件

例如。

  1. 创建engine、session_factory和scoped_session对象。

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)
  • 创建中间件。

  • 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()
    
  • 注册中间件。

    import falcon
    
    
    app = falcon.API(middleware=[
        SQLAlchemySessionManager(Session),
    ])
    
  • 会话在每个请求中都是可访问的。

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

    这真的很有帮助。一个快速的问题,应该是 resource.session.close() 还是 resource.session.remove() - misakm
    3
    根据http://docs.sqlalchemy.org/en/rel_1_1/orm/contextual.html#using-thread-local-scope-with-web-applications,应该使用`Session.remove()`,而不是其他方法。 - Ronald
    6
    那么应该不是 self.Session.remove() 吗? - bmelton
    你和 https://eshlox.net/2019/05/28/integrate-sqlalchemy-with-falcon-framework-second-version/ 相比如何?remove 方法中是否集成了回滚支持?编辑:close 方法似乎在底层使用回滚 https://docs.sqlalchemy.org/en/13/orm/contextual.html - Ambroise Rabier

    1

    在pypi上有一个名为falcon-sqla的包,它提供了一个中间件来管理Falcon和SQLAlchemy的会话。

    它使用请求上下文对象为每个http请求添加不同的会话,避免使用作用域会话的需要。


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接