在StackOverFlow中看到这个问题,比较有意思How to close a SQLAlchemy session?

题目

继续我们在How to close sqlalchemy connection in MySQL的讨论,我检查了SQLAlchemy创建的到数据库的连接,然后我发现我不能关闭它们,除非退出Python

如果我在python控制台中运行这一段程序,它将会保持session打开一直到我退出Python

1
2
3
4
5
6
7
8
9
10
11
from sqlalchemy.orm import sessionmaker
from models import OneTable, get_engine
engine = get_engine(database="mydb")
session = sessionmaker(bind=engine)()
results = session.query(OneTable.company_name).all()
# some work with the data #
session.close()

唯一我发现的解决方式是engine.dispose()

按照我给出连接的讨论,我的问题是:

  • 为什么engine.dispose()是关闭session所必须的
  • session.close()不够吗

回答

高票回答:

这主要是对session这个词有混淆。你可能混淆了SQLAlchemy SessionMySQL session,后者指的是当你第一次连接到MySQL和断开连接之间这一段范围。

这两个概念是不同的,SQLAlchemy Session指的是一个或者多个transactions的范围,在一个特定的数据库连接之上。

因此,就你所问的答案应该是调用session.close(),也就是,如何正确的关闭SQLAlchemy Session

然后,剩下的问题说明你想凭借一些功能性的东西,当特定的Session关闭时候,而且真实的DBAPI连接也要关闭

也就是说你希望禁止connection pooling连接池,就像其他答案一样,非常容易,使用NullPool,poolclass=NullPool

后记

最近在应用中出现了这个问题Too many open files:/sqlalchemy/dialects

首先这个too many open files原因是因为程序打开的文件/socket连接数量超过系统设定值,然后又是sqlalchemy报错的,因此很大可能性是因为sqlalchemy建立的连接过多。

然后给所有使用db.session.commit()的后面加入一行db.session.close()用来关闭连接会话。

看来涉及数据库连接等连接问题时候还是得谨慎啊。