2016-11-28 165 views
1

独特SQLAlchemy的数据库连接,我有这个金字塔的应用:如何确保与uWSGI和金字塔

from pyramid.config import Configurator 
from pyramid.response import Response 

from sqlalchemy import create_engine 
from sqlalchemy.pool import QueuePool 
from sqlalchemy.sql import text 

POOL_SIZE = 10 
try: 
    import uwsgi 
    POOL_SIZE = int(uwsgi.opt['threads']) 

    def postfork(): 
     engine.dispose() 
    uwsgi.post_fork_hook = postfork 
except ImportError: 
    pass 

DBURL = 'postgres://postgres:[email protected]:5455/postgres' 
engine = create_engine(DBURL, poolclass=QueuePool, pool_size=POOL_SIZE) 

def db_conn(request): 
    conn = engine.contextual_connect() 
    def cleanup(request): 
     conn.close() 
    request.add_finished_callback(cleanup) 
    return conn 

def some_view(request): 
    conn = request.db_conn 
    with conn.begin() as trans: 
     s = text('SELECT 1') 
     cur = conn.execute(s) 
     result = cur.first() 
    return Response('<h1>{}</h1>'.format(result)) 

def main(): 
    config = Configurator() 
    config.add_request_method(db_conn, reify=True) 
    config.add_route('some_view', '/') 
    config.add_view(some_view, route_name='some_view') 
    app = config.make_wsgi_app() 
    return app 

application = main() 

我敢用uWSGI运行:

uwsgi --wsgi-file webapp.py --http :9090 --master --processes 2 --threads 2 

我的主要问题是,如果该代码是正确。我可以确定不同的进程/线程将使用不同的连接吗?

我有2个进程,每2个线程,和我的假设是:

  • 调用在uWSGI叉后钩engine.dispose()确保每个进程都有它自己的连接

  • 调用​​将向请求添加一个SQLAlchemy连接对象。在引擎盖下,使用线程本地来确保线程之间的不同连接

  • 我得到的连接调用contextual_connect(),而不是只是connect(),但我认为这并不重要,我用哪种方法。

但我不知道他们是否正确,特别是第二。

最后一句话,我知道SQLAlchemy的scoped_sessionsessionmaker,但我想直接使用连接对象来更好地理解它是如何工作的。

+0

如果您希望避免post-fork问题,则可以在第一个HTTP请求请求数据库连接时懒惰地创建池。这会简化代码。您可以将它作为'request.registry.pool'存储在金字塔中,并且将在过程中共享。 –

回答

2

我没有看到您的示例代码有任何问题。我也同意,我认为你应该只使用connect()而不是contextual_connect()