SQLAlchemy 中的连接池回收不会从 pg_stat_activity 回收空闲状态的连接

Connection pool recycle in SQLAlchemy does not recycle idle stated connections from pg_stat_activity

我有一个 Flask 应用程序,它使 insertselectupdate 使用 SQLAlchemy 作为其 ORM 和 PostgreSQL 作为数据库管理系统的查询。最小的工作示例是:

import config as cfg
from flask import Flask
from extensions import db


flask_app = Flask(__name__)
flask_app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
flask_app.config['SQLALCHEMY_DATABASE_URI'] = cfg.POSTGRES_DB_CONNECT
flask_app.config['SQLALCHEMY_ENGINE_OPTIONS'] = {"pool_pre_ping": True,
                                                 "pool_recycle": 600}
flask_app.secret_key = cfg.SECRET_KEY

db.init_app(flask_app)

if __name__=="__main__":
    app.run()

如您所见,pool_recycle parameter is set to 600, so that it can close connections older than 10 minutes. However, when I check my pg_stat_activity,它显示 空闲状态 连接长达 2 小时。我使用此查询来检查 pg_stat_activity:

SELECT * FROM pg_stat_activity WHERE client_addr='my_service_hostname' ORDER BY query_start DESC;

我不明白为什么这些查询保持空闲状态,并且在查询开始后 10 分钟内没有消失。也许我的错误在于我对连接池的工作原理知之甚少。有没有办法让连接在10分钟内关闭?

更新 1:这是我使用任何查询的视图函数的最小工作示例:

import config as cfg
import os
from flask import request
from models.document import Document
from app import flask_app, ps_work
from extensions import db
from file_processors import common, documents

@flask_app.route("/files/<string:uuid>", methods=['POST'])
def upload(uuid):
    file = request.files['file']
    file_uuid = uuid.lower()
    if file:
        filename = common.Secure_Filename(request.form.get('name', file.filename)).secure_filename()
        db_file = Document(file_uuid, filename)
        db.session.add(db_file)
        db.session.commit()

        # HERE I DO SOME UPDATE
        while not ps_work.check_file_exists(os.path.join(path,filename)):
            file_vault_file_path = db_file.upload_file(path, filename)
        db.session.commit()

        # HERE I ALSO DO SOME UPDATE
        db_file.extract_text(filename)
        db_file.sooner_update(extension)
        db.session.commit()

有没有可能我的错误是使用 db.session.commit 3 次,而不是使用 db.session.flush 2次,最后是db.session.commit?

我对池的细节没有太多经验,但文档表明连接似乎只有在请求时才会被回收。因此,如果未使用大量连接,则连接可能会持续超过回收限制。你能描述一下用法吗?

https://docs.sqlalchemy.org/en/14/core/pooling.html#setting-pool-recycle

Note that the invalidation only occurs during checkout - not on any connections that are held in a checked out state.

实际上,我似乎没有正确理解连接池的工作原理。我的解决方案是将 NullPool class 作为 pool_class 参数设置为 flask_app.config['SQLALCHEMY_ENGINE_OPTIONS'].