Python StreamingHttpResponse:返回到池的数据库连接/关闭它

Python StreamingHttpResponse:返回到池的数据库连接/关闭它,python,django,postgresql,pytest,gevent,Python,Django,Postgresql,Pytest,Gevent,如果您有一个从Django视图返回的StreamingHttpResponse,它何时返回到池的任何数据库连接?如果默认情况下,在StreamingHttpResponse完成后执行此操作,是否有方法使连接更早返回 def my_view(request): # Some database queries using the Django ORM # ... def yield_data(): # A generator, with no database queries

如果您有一个从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
  )

如果有区别的话,这是与gunicorn一起使用的,任何答案在使用
pytest.mark.django_db
(我认为它在事务中封装了测试)

进行测试时都应该有效,如果您查看文档的话

连接管理

Django在第一次进行数据库查询时打开与数据库的连接。它保持此连接打开,并在后续请求中重用它。Django在连接超过CONN_MAX_age定义的最大期限或不再可用时关闭连接

具体地说,Django会在需要连接但还没有连接的时候自动打开到数据库的连接,这可能是因为这是第一个连接,也可能是因为上一个连接已关闭

在每个请求开始时,Django会关闭连接(如果连接已达到最大期限)。如果数据库在一段时间后终止空闲连接,则应将CONN_MAX_AGE设置为较低的值,以便Django不会尝试使用已由数据库服务器终止的连接。(此问题可能只影响流量非常低的站点。)

在每个请求结束时,Django会关闭连接,如果连接已达到最大使用期限或处于不可恢复的错误状态。如果在处理请求时发生任何数据库错误,Django将检查连接是否仍然有效,如果无效,则关闭连接。因此,数据库错误最多影响一个请求;如果连接变得不可用,下一个请求将获得一个新的连接

另外,如果您在
django
源代码中看到
db/\uuuu init\uuuu.py

#用于向后兼容。首选连接['default']。
connection=DefaultConnectionProxy()
#注册事件以在Django请求启动时重置保存的查询。
def重置_查询(**kwargs):
对于conn in连接。all():
conn.querys\u log.clear()
信号。请求\u已启动。连接(重置\u查询)
#注册事件以重置事务状态并关闭过去的连接
#他们的一生。
def关闭旧连接(**kwargs):
对于conn in连接。all():
如果不可用或过时,则连接关闭()
信号。请求已启动。连接(关闭旧连接)
信号。请求完成。连接(关闭旧连接)
它已连接到
请求\u已启动
请求\u已完成
信号,以使用
关闭旧连接

因此,如果您不愿意等待连接关闭,您可以自己调用此方法。您更新的代码如下所示

从django.db导入关闭旧连接
定义我的视图(请求):
#使用Django ORM的一些数据库查询
# ...
关闭旧的连接()
def yield_data():
#生成器,不使用Django ORM进行数据库查询
# ...
返回StreamingHttpResponse(
产量数据(),状态=200
)

您不应该调用
yield\u data
,因为这样它当然会首先计算函数
yield\u data
(直到结束)。@WillemVanOnsem
yield\u data
是一个生成器(即在定义中带有
yield
)。我认为在调用它的返回值被迭代之前,调用它不会起任何作用?我添加了一条注释,以便更清楚地说明它是一个生成器。@MichaCharemza:啊,是的,那么它确实是正确的。
如果
我的视图
被包装在一个事务中,比如在from
pytest.mark.django\u db
浏览代码时,
是否会导致任何问题,看起来它不应该对您的测试产生影响。如果您有任何问题,请告诉我