8

我正在用 Python 构建一个 Web 应用程序(使用 Flask)。我不打算使用 SQLAlchemy 或类似的 ORM 系统,而是直接使用 Psycopg2。

我应该为每个新请求打开一个新的数据库连接(然后关闭它)吗?或者我应该使用一些东西来汇集这些连接?

4

5 回答 5

10

PgBouncer 对应用程序和服务器来说非常简洁和透明。

我们已经在生产中使用 PgBouncer 2 年了,没有一个问题。这是一个非常棒的 PostgreSQL 连接池。

http://wiki.postgresql.org/wiki/PgBouncer

于 2012-08-09T17:51:43.840 回答
7

是的,连接池会有所帮助,但是是的,您必须根据数据库上的负载来找出实时连接或池大小的正确数字。

    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
于 2015-09-29T08:47:00.980 回答
3

答案取决于将发生多少这样的请求以及在您的 Web 应用程序中同时发生多少?如果您希望您的 Web 应用程序忙于同时登录的 100 甚至 1000 名用户,那么连接池通常是一个更好的主意。如果您只是将其作为一个辅助项目并且期望少于几百个用户,您可能会逃脱没有汇集。

于 2012-08-09T18:24:12.837 回答
1

如果此应用程序要同时为多个客户端提供服务,我认为连接池是最好的选择。

于 2012-08-09T17:50:37.950 回答
1

在 Flask、FastAPI 和所有依赖于具有多个工作人员的 wsgi/asgi 专用服务器的环境中,池化似乎是完全不可能的。这种行为的原因很简单:您无法控制池和主线程/进程。池实例仅可用于为一组客户端服务的单个线程 - 因此仅适用于一个工作人员。任何其他工作人员都将获得它自己的池,因此不能共享已建立的连接。

从逻辑上讲,这也是不可能的,因为您无法使用 python (2.x - 3.8) 在多核环境中的线程/进程之间共享这些对象状态。

于 2020-04-07T10:44:20.147 回答