如何确保与 uWSGI 和 Pyramid 的唯一 SQLAlchemy 数据库连接
How to ensure unique SQLAlchemy database connections with uWSGI and Pyramid
我有这个金字塔应用程序:
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:pass@127.0.0.1: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
我的主要问题是该代码是否正确。我可以确定不同的 processes/threads 会使用不同的连接吗?
我有 2 个进程,每个进程有 2 个线程,我的假设是:
在 uWSGI post-fork 钩子中调用 engine.dispose()
确保每个进程都有自己的连接
调用config.add_request_method(db_conn, reify=True)
将向请求添加一个 SQLAlchemy 连接对象。在引擎盖下,使用线程本地来确保线程之间的不同连接
我正在获取连接调用 contextual_connect()
而不是 connect()
,但我认为使用哪种方法并不重要。
但我不确定他们是否正确,特别是第二个。
最后一点,我知道 SQLAlchemy 的 scoped_session
和 sessionmaker
,但我想直接使用连接对象以更好地理解它是如何工作的。
我没有发现您的示例代码有任何问题。我也同意,我认为你应该只使用 connect()
而不是 contextual_connect()
.
我有这个金字塔应用程序:
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:pass@127.0.0.1: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
我的主要问题是该代码是否正确。我可以确定不同的 processes/threads 会使用不同的连接吗?
我有 2 个进程,每个进程有 2 个线程,我的假设是:
在 uWSGI post-fork 钩子中调用
engine.dispose()
确保每个进程都有自己的连接调用
config.add_request_method(db_conn, reify=True)
将向请求添加一个 SQLAlchemy 连接对象。在引擎盖下,使用线程本地来确保线程之间的不同连接我正在获取连接调用
contextual_connect()
而不是connect()
,但我认为使用哪种方法并不重要。
但我不确定他们是否正确,特别是第二个。
最后一点,我知道 SQLAlchemy 的 scoped_session
和 sessionmaker
,但我想直接使用连接对象以更好地理解它是如何工作的。
我没有发现您的示例代码有任何问题。我也同意,我认为你应该只使用 connect()
而不是 contextual_connect()
.