SQLAlchemy连接池和会话

21

最近我开始使用 SQLAlchemy,试图理解在一个 web-applicationconnection poolsession 的工作方式。

我正在使用 flask 构建一个 API

__init__.py

engine = create_engine('mysql://username:password@localhost/my_database') 
DBSession = sessionmaker(bind=engine)

views.py

@app.route('/books', methods = ['GET'])
def getBooks():
    session = DBSession()
    returnedBooks = session.query(BOOK).all()
    session.close()

    return something...

1) 首先,如果我没有明确关闭session对象,那么在request处理完成后它会自动关闭吗?

2) 当我的应用程序收到多个requests时,所有创建的多个session对象是否都链接到在__init__.py文件中创建的单个engine对象?

3) 在view.py中创建的session对象是connection pool持有的connections吗?如果是的话,并且这些未被关闭,那么新的连接是否必须为随后的请求而创建?

4) 我应该在某个时候使用dispose()吗?

1个回答

29

首先,如果我没有明确关闭我的会话对象,那么它会在请求处理后自动关闭吗?

垃圾回收器最终*将调用__del__函数关闭该会话。如果您没有以其他方式整理该会话,这可能会导致回滚。通常情况下,您应该做类似以下的操作:

import contextlib
def myRequestHandler(args):
    with contextlib.closing(DBSession()) as session:
        result = do_stuff(session)
        if neccesary:
            session.commit() 
        else:
            session.rollback()
        return result

2) 当我的应用程序接收到多个请求时,所有创建的多个会话对象是否都链接到在我的 __init__.py 文件中创建的单个引擎对象?

是的,sessionmaker() 包含了所有 Session 的配置信息。使用您的模式,每个请求都会得到一个新的会话对象,这是一件好事。

3) 在 view.py 中创建的会话对象是连接池持有的连接吗?

会话和连接 不是同一回事;虽然每个会话只使用一个连接,并在完成后将其返回到池中。

如果是这样,并且它们没有关闭,那么后续请求是否需要创建新的连接?

不同的池实现 有不同的规则,但对于大多数数据库引擎,默认值为 QueuePool;它具有默认的最大连接数为15个。后续请求需要额外的连接时,将阻塞或超时。尽可能重用连接。

4) 我应该在某个时候使用 dispose() 吗?

通常情况下不需要,如果您还在使用池和引擎和会话,则除了提交/回滚会话之外的任何其他资源管理都可能是不必要的。

* eventually 实际上意味着在立即和永远之间的某个时间点;不要指望它能提供有用的工作;请注意,当进程死亡时,操作系统将强制关闭连接,因此使用 GC 进行连接管理并没有什么实质性的好处。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接