【问题标题】:SQLAlchemy leaving sessions in 'idle' state even after session.close() and pool_size=5即使在 session.close() 和 pool_size=5 之后,SQLAlchemy 也会使会话处于“空闲”状态
【发布时间】:2018-10-01 18:02:05
【问题描述】:

我将 SQLAlchemy 和 psycopg2 与 PostgreSQL 一起使用。当我查看带有SELECT * FROM pg_stat_activity 的pg_stat_activity 表时,我的会话保持在idle 状态。在几分钟的过程中,我将在“空闲”状态下进行多达 15-20 个会话。这些连接都是

我的代码正在执行 dbsession.commit() 和 dbsession.close() 并且我的 pool_size 是默认值 5。当 pool_size 为 5 时,我如何在数据库端打开 15-20 个会话?如何限制数量?

以下是我的 dbsessions 和 create_engine 函数。

def processor(self, ids):
    logger.debug("Starting database connection")
    dbmanager = DatabaseManager(self.db_config)
    dbsession = dbmanager.get_db_session()
    logger.debug("Database session successfully created")
    rows = dbsession.query(TableA, TableB)\
        .filter(and_(TableA.id.is_(None), TableA.id.in_([ids])))\
        .outerjoin(TableB)\
        .all()
    for index, row in enumerate(rows):
        //processing code
    logger.debug("Committing data to database")
    dbsession.commit()
    dbsession.close()

我的 dbmanager 类

from sqlalchemy import create_engine
from sqlalchemy.engine.url import URL
from sqlalchemy.orm import sessionmaker

class DatabaseManager(object):

    def __init__(self, configuration):

        self.config = configuration

    def get_database_connection_string(self):

        db_url = {'drivername': self.config["dialect"],
                  'username': self.config["username"],
                  'password': self.config["password"],
                  'host': self.config["host"],
                  'database': self.config["database"],
                  'port': 5432}
        return URL(**db_url)

    def create_db_engine(self):
        connection_url = self.get_database_connection_string()
        engine = create_engine(connection_url)
        return engine

    def create_db_session(self, dbengine):
        Session = sessionmaker()
        Session.configure(bind=dbengine)
        dbsession = Session()
        return dbsession

    def get_db_session(self):
        engine = self.create_db_engine()
        session = self.create_db_session(engine)
        return session

当我从 pg_stat_activity 运行选择时我会看到什么。

'Client','ClientRead','idle',,,'COMMIT','client backend'
'Client','ClientRead','idle',,,'COMMIT','client backend'
'Client','ClientRead','idle',,,'COMMIT','client backend'
'Client','ClientRead','idle',,,'COMMIT','client backend'
'Client','ClientRead','idle',,,'COMMIT','client backend'
'Client','ClientRead','idle',,,'COMMIT','client backend'
'Client','ClientRead','idle',,,'COMMIT','client backend'
'Client','ClientRead','idle',,,'COMMIT','client backend'
'Client','ClientRead','idle',,,'COMMIT','client backend'
'Client','ClientRead','idle',,,'COMMIT','client backend'

【问题讨论】:

  • 你能找到原因吗?我也面临同样的问题。
  • 我认为这个线程中的其他响应没有帮助?这是不久前的事了,不相信我曾经修过它。

标签: python postgresql sqlalchemy


【解决方案1】:

我相信这是因为您每次创建一个新的Session 时都会创建一个Engine,而不是创建一个Engine 并从中生成Sessions。

这将导致所有会话通过单个 Engineproxied

所以这个类应该是这样的

class DatabaseManager(object):

    def __init__(self, configuration):

        self.config = configuration
        self.engine = this.create_db_engine()

    def get_database_connection_string(self):

        db_url = {'drivername': self.config["dialect"], ....
        return URL(**db_url)

    def create_db_engine(self):
        connection_url = self.get_database_connection_string()          
        return create_engine(connection_url)

    def create_db_session(self):
        Session = sessionmaker()
        Session.configure(bind=self.engine)
        dbsession = Session()
        return dbsession

    def get_db_session(self):
        session = self.create_db_session()
        return session

我通常也重复使用相同的事务(Session)而不是每次都重新生成一个Session

class DatabaseManager(object):

    def __init__(self, configuration):
        ...
        self.session = None   // Added

    def get_db_session(self):
        if not self.session:
            self.session = self.create_db_session()

        return self.session

实际上永远不要关闭它,因为我在 Apache 模式下使用 CGI ...

【讨论】:

    猜你喜欢
    • 2014-04-24
    • 1970-01-01
    • 2017-10-31
    • 1970-01-01
    • 2012-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-08
    相关资源
    最近更新 更多