python - StreamingHttpResponse : return database connection to pool/close it

标签 python django postgresql pytest gevent

如果您有 StreamingHttpResponse从 Django View 返回,它何时返回任何数据库连接到池?如果默认情况下它会执行一次 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 opens a connection to the database when it first makes a database query. It keeps this connection open and reuses it in subsequent requests. Django closes the connection once it exceeds the maximum age defined by CONN_MAX_AGE or when it isn’t usable any longer.

In detail, Django automatically opens a connection to the database whenever it needs one and doesn’t have one already — either because this is the first connection, or because the previous connection was closed.

At the beginning of each request, Django closes the connection if it has reached its maximum age. If your database terminates idle connections after some time, you should set CONN_MAX_AGE to a lower value, so that Django doesn’t attempt to use a connection that has been terminated by the database server. (This problem may only affect very low traffic sites.)

At the end of each request, Django closes the connection if it has reached its maximum age or if it is in an unrecoverable error state. If any database errors have occurred while processing the requests, Django checks whether the connection still works, and closes it if it doesn’t. Thus, database errors affect at most one request; if the connection becomes unusable, the next request gets a fresh connection.


此外,如果您看到 db/__init__.pydjango源代码
# 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_startedrequest_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
  )

关于python - StreamingHttpResponse : return database connection to pool/close it,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61417702/

相关文章:

python - 我如何让 IPython 按类组织制表符补全的可能性?

python - Beautifulsoup:如果标签或元素未知,如何查找字符串?

django - Django过滤查询外键

python - Django:按日期范围过滤对象

python - 在 Django 中使用文本作为安全文本和 url

sql - 将 postgres 表与 json 数据同步

postgresql - 像 excel 一样创建 Postgres Pivot

Python:带有枚举的 os.walk()

python - 在 nvidia jetson tx2 上安装 tensorflow 的问题

sql - 使用 PostgreSQL 地理类型函数的问题 - PostGIS(扩展)