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

Max*_*ysh 6 django django-tests python-asyncio django-channels 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)

Run Code Online (Sandbox Code Playgroud)

Postgres 错误:

django.db.utils.OperationalError: database "test_mydbname" is being accessed by other users
Run Code Online (Sandbox Code Playgroud)

SQLite 错误:

sqlite3.OperationalError: database table is locked: test_mydbname
Run Code Online (Sandbox Code Playgroud)

我尝试过从 django-channels 进行交换sync_to_asyncdatabase_sync_to_async但这并没有改变任何东西。

我怎样才能解决这个问题?

Mat*_*ard 2

问题在于异步运行循环如何与主线程交互,自己处理这个问题可能会变得非常复杂。

对于测试,django-channels我建议使用pytestwithpytest-asyncio来测试通道。而且当然pytest-django

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

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

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