2016-11-28 159 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()