SQLAlchemy使用和踩坑记 - 知乎
2、长时间未请求连接自动断开
现象:长时间服务端没有连接数据库,数据库连接自动断开
原因:1、sqlalchemy在create_engine时,使用连接池并没有指定连接池回收时间,则连接池的连接不会自动被回收,并默认使用QueuePool进行连接池管理,调用session.close(),不会断开连接,2、数据库,例如mysql会设置一个wait_timeout(默认8个小时),当连接空闲8个小时,则自动断开
解决方案:
- 方案一:修改数据库的设置 wait_timeout(不推荐)
- 方案二:新建连接池时,设置连接回收时间,使这个值小于wait_timeout,sqlchemy的create_engine一些重要参数如下:
create_engine重要参数:
pool_size:连接数,采用了惰性思想,例如:pool_size=10,如果项目中只使用了5个,则连接池中的连接数,只有5个,但当项目同时使用了10个连接,则后续连接池中的连接数为10个
max_overflow:超出连接数时,允许再新建的连接数,例如:pool_size=10,max_overflow=8,最大连接数18个,但其中8个不在使用时,直接回收,连接池中的连接数为10个
pool_timeout:等待可用连接时间,超时则报错,默认为30秒
pool_recycle:连接生存时长,超过则该连接被回收,再生存新连接,可把这个值改成小于wait_timeout;设置-1时,则不回收连接
- 方案三:不使用链接池,在create_engine时指定连接池为NullPool,则使用session.close()后断开数据库链接
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.pool import NullPool
class DbHandler(object):
def __init__(self):
self.db_addr = "XXXXXX"
def create_session(self):
engine = create_engine(self.db_addr, poolclass=NullPool)
session = sessionmaker(bind=engine)()
return session
3、全局session在多进程下被断开
想象:sqlalchemy连接池,经常报错:mysql server has gone away
原因:父进程创建子进程,子进程会使用父进程的数据连接,当子进程执行完成,断开数据库的连接,则全局session和连接被释放,后续要使用连接数据库时,则报错
解决方案:多进程中,尽量没有进程新建连接和session