我正在用Python构建一个Web应用程序(使用Flask)。我不打算使用SQLAlchemy或类似的ORM系统,而是直接使用Psycopg2。
我应该为每个新请求打开一个新的数据库连接(并随后关闭它)吗?或者我应该使用什么来汇集这些连接?
答案 0 :(得分:10)
PgBouncer对应用程序和服务器非常简洁透明。
我们已经在生产中使用PgBouncer 2年而没有一个问题。这是一个非常棒的PostgreSQL连接池。
答案 1 :(得分:4)
是的连接池会有所帮助,但是你必须根据数据库中的负载找出实时连接或池大小的正确数字。
from psycopg2.pool import SimpleConnectionPool
from contextlib import contextmanager
dbConnection = "dbname='dbname' user='postgres' host='localhost' password='postgres'"
# pool define with 10 live connections
connectionpool = SimpleConnectionPool(1,10,dsn=dbConnection)
@contextmanager
def getcursor():
con = connectionpool.getconn()
try:
yield con.cursor()
finally:
connectionpool.putconn(con)
def main_work():
try:
# with here will take care of put connection when its done
with getcursor() as cur:
cur.execute("select * from \"TableName\"")
result_set = cur.fetchall()
except Exception as e:
print "error in executing with exception: ", e
答案 2 :(得分:2)
答案取决于您的网络应用程序中会发生多少次此类请求以及同时发生多少次请求?如果您希望您的Web应用程序忙于同时登录的100个甚至1000个用户,那么连接池通常是一个更好的主意。如果您只是作为一个侧面项目并且期望少于几百个用户,那么您可能会离开没有合并。
答案 3 :(得分:1)
我认为如果此应用程序要同时为多个客户端提供服务,那么连接池是最好的选择。
答案 4 :(得分:1)
在Flask,FastAPI和一切依赖于具有多个工作程序的wsgi / asgi专用服务器的环境中,池化似乎是完全不可能的。 此行为的原因很简单:您无法控制池和主线程/进程。 池实例仅可用于服务一组客户端的单个线程-因此仅适用于一个工作线程。任何其他工作者都将获得它自己的池,因此不能共享已建立的连接。
从逻辑上讲也是不可能的,因为您无法在多核环境中使用python(2.x-3.8)在线程/进程之间共享这些对象状态。