我正在使用SQLAlchemy和psycopg2与PostgreSQL。当我使用idle
查看pg_stat_activity表时,我的会话保持在SELECT * FROM pg_stat_activity
状态。在几分钟的过程中,我将在“闲置”状态下达到15-20个会话。这些连接都是< 5分钟。
我的代码正在执行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运行select时,我会看到什么。
'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'
答案 0 :(得分:0)
我相信是因为您每次创建一个新的Engine
时都会创建一个Session
,而不是一次创建一个Engine
并从中生成Session
这将导致所有会话通过一个proxied
进入Engine
所以类应该看起来像这样
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
...