有一篇关于这个问题的文章,不幸的是它是俄语的。让我引用最后一部分:
所有的连接都存储在django.db.connections中,它是django.db.utils.ConnectionHandler的实例。每次 ORM 即将发出查询时,它都会通过调用
connections['default']来请求数据库连接。反过来,ConnectionHandler.__getattr__检查 ConnectionHandler._connections 中是否存在
连接,如果它为空,则创建一个新连接。
使用后应关闭所有打开的连接。有一个信号
request_finished,由
django.http.HttpResponseBase.close运行。Django 在最后一刻关闭了数据库连接,当时没有人可以再使用它了——这似乎是合理的。
然而,关于 ConnectionHandler 如何存储数据库连接有一个棘手的部分。它使用threading.local,在猴子补丁后变成
gevent.local.local。声明过一次,这个结构就像它在每个绿地都是独一无二的一样工作。控制器 *some_view* 在一个 greenlet 中开始工作,现在我们在 *ConnectionHandler._connections* 中建立了一个连接。然后我们再创建几个greenlet,它们得到一个空的*ConnectionHandlers._connections*,它们从池中得到connectinos。完成新的 greenlets 后,它们的 local() 的内容消失了,数据库连接也随之消失,而没有返回到池中。在某个时刻,池变空
开发 Django+gevent 时,您应该始终牢记这一点,并通过调用django.db.close_connection关闭数据库连接。它也应该在异常时调用,您可以为此使用装饰器,例如:
class autoclose(object):
def __init__(self, f=None):
self.f = f
def __call__(self, *args, **kwargs):
with self:
return self.f(*args, **kwargs)
def __enter__(self):
pass
def __exit__(self, exc_type, exc_info, tb):
from django.db import close_connection
close_connection()
return exc_type is None