Django 3.0-异步测试后未关闭数据库连接

时间:2020-02-15 19:33:51

标签: django python-asyncio django-channels django-tests asgi

我在异步代码内使用Django ORM。一切正常,所有测试通过。但是,测试后数据库连接无法正确关闭。这是一个示例:

from asgiref.sync import sync_to_async, async_to_sync


@sync_to_async
def count_books():
    return Book.objects.count()


class FooTest(TestCase):
    def setUp(self):
        Book.objects.create(title='Haha')

    def test1(self):
        import asyncio
        c = asyncio.run(count_books())
        self.assertEqual(1, c)

    def test2(self):
        c = async_to_sync(count_books)()
        self.assertEqual(1, c)

Postgres错误:

django.db.utils.OperationalError: database "test_mydbname" is being accessed by other users

Sqlite错误:

sqlite3.OperationalError: database table is locked: test_mydbname

我曾尝试从Django频道中将sync_to_asyncdatabase_sync_to_async交换,但这并没有改变。

我该如何解决?

1 个答案:

答案 0 :(得分:2)

问题与异步运行循环与主线程的交互方式有关,您自己进行处理可能会变得非常复杂。

对于测试django-channels,我建议将pytestpytest-asyncio一起使用以测试频道。当然还有pytest-django

这将提供一些有用的工具来测试异步代码。

@pytest.mark.django_db(transaction=True)
@pytest.mark.asyncio
async def test1():
    count = await database_sync_to_async(Book.objects.count)
    ....

有关如何测试通道代码的一些示例,请查看here