django - 如何在 Django 中测试关闭数据库连接的方法?

标签 django django-testing django-database

我有一个长时间运行的 Python 进程,它使用 Django ORM。它看起来像这样:

import django
from django.db import connection

from my_app import models


def my_process():
    django.setup()
    while (True):
        do_stuff()
        connection.close()
        models.MyDjangoModel().save()

有时 do_stuff需要很长时间,此时我遇到了一个错误,我的 MySql 连接超时,因为数据库服务器在空闲时终止了连接。添加 connection.close() line 强制 django 每次都获得一个新的连接并修复该问题。 (见 https://code.djangoproject.com/ticket/21597)。

但是,我正在使用 django.test.TestCase 测试此过程。 ,并调用 connection.close导致这些测试失败,如 Django 的 TestCase类将测试包装在一个事务中,关闭该事务中的连接会导致事务中断并引发 django.db.transaction.TransactionManagementError .

我尝试解决此问题的一种尝试是设置 CONN_MAX_AGE数据库参数和调用 connection.close_if_unusable_or_obsolete相反,但事务也改变了连接的 autocommit设置的默认值 TrueFalse这反过来导致 close_if_unusable_or_obsolete无论如何都要尝试关闭连接( https://github.com/django/django/blob/master/django/db/backends/base/base.py#L497 )。

我想我也可以模拟 connection.close在测试中所以它什么都不做,但这似乎有点hacky。

测试需要关闭数据库连接的 django 方法的最佳方法是什么?

最佳答案

好吧,我不确定这是否是最好的答案,但由于到目前为止这个问题没有得到任何回应,我将发布我最终用于后代的解决方案:

我创建了一个辅助函数,它在关闭连接之前检查我们当前是否处于原子块中:

import django
from django.db import connection

from my_app import models


def close_connection():
    """Closes the connection if we are not in an atomic block.

    The connection should never be closed if we are in an atomic block, as
    happens when running tests as part of a django TestCase. Otherwise, closing
    the connection is important to avoid a connection time out after long actions.     
    Django does not automatically refresh a connection which has been closed 
    due to idleness (this normally happens in the request start/finish part 
    of a webapp's lifecycle, which this process does not have), so we must
    do it ourselves if the connection goes idle due to stuff taking a really 
    long time.
    """
    if not connection.in_atomic_block:
        connection.close()


def my_process():
    django.setup()
    while (True):
        do_stuff()
        close_connection()
        models.MyDjangoModel().save()

正如评论所述,close_connection防止 connection.close从被测试调用,所以我们不再破坏测试事务。

关于django - 如何在 Django 中测试关闭数据库连接的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39217508/

相关文章:

python - 没有名为 dateutil.parser 的模块

django - 通过 mod_wsgi 从 apache 传递环境变量以在 django 1.11 设置中使用

python - 当一组更改时更改模型

python - 如何对 ValidationError 进行单元测试并断言使用了正确的代码?

javascript - 我可以将 jQuery.post() 与 LiveServerTestCase 一起使用吗?

python - AWS - DJANGO - 格式化错误 : OperationalError: fe_sendauth: no password supplied

Django 迁移 RunSQL 以数据库类型为条件

python - 如何获取值为列表的分隔查询集?

python - 如何测试 Django 自定义过滤器?

python - Django:首先按最后一个条目对数据库导入进行排序,依此类推