如果您从Django视图返回了StreamingHttpResponse
,它何时将任何数据库连接返回到池?如果默认情况下在StreamingHttpResponse
完成后执行此操作,是否有办法更早地返回连接?
def my_view(request):
# Some database queries using the Django ORM
# ...
def yield_data():
# A generator, with no database queries using the Django ORM
# ...
return StreamingHttpResponse(
yield_data(), status=200
)
[如果有所作为,这是将https://pypi.org/project/django-db-geventpool/与Gunicorn一起使用,并且在使用pytest.mark.django_db
进行测试(我认为将测试包装在交易中)时,任何答案也应该有效。
如果您查看文档
https://docs.djangoproject.com/en/3.0/ref/databases/
连接管理
Django在首次进行数据库查询时会打开与数据库的连接。它使该连接保持打开状态,并在后续请求中重用它。超过CONN_MAX_AGE定义的最长期限或不再可用时,Django将关闭连接。
详细来说,Django会在需要数据库且尚不存在时自动打开与数据库的连接-要么是因为这是第一个连接,要么是因为上一个连接已关闭。
在每个请求的开始,如果Django已达到其最大使用期限,则会关闭该连接。如果您的数据库在一段时间后终止了空闲连接,则应将CONN_MAX_AGE设置为较低的值,以便Django不会尝试使用已被数据库服务器终止的连接。 (此问题可能只影响流量非常小的站点。)
在每个请求结束时,如果Django已达到其最大使用期限或处于不可恢复的错误状态,它将关闭该连接。如果处理请求时发生任何数据库错误,则Django会检查连接是否仍然有效,如果没有,则将其关闭。因此,数据库错误最多影响一个请求。如果连接不可用,则下一个请求将获得新的连接。
也可以在db/__init__.py
源代码中看到django
# For backwards compatibility. Prefer connections['default'] instead.
connection = DefaultConnectionProxy()
# Register an event to reset saved queries when a Django request is started.
def reset_queries(**kwargs):
for conn in connections.all():
conn.queries_log.clear()
signals.request_started.connect(reset_queries)
# Register an event to reset transaction state and close connections past
# their lifetime.
def close_old_connections(**kwargs):
for conn in connections.all():
conn.close_if_unusable_or_obsolete()
signals.request_started.connect(close_old_connections)
signals.request_finished.connect(close_old_connections)
与request_started
和request_finished
信号连接,以使用close_old_connections
关闭旧连接。
因此,如果您不愿意等待连接关闭,则可以自己调用此方法。您更新的代码如下所示
from django.db import close_old_connections
def my_view(request):
# Some database queries using the Django ORM
# ...
close_old_connections()
def yield_data():
# A generator, with no database queries using the Django ORM
# ...
return StreamingHttpResponse(
yield_data(), status=200
)