Reputation: 31615
I use Django ORM inside async code. Everything works fine and all tests pass. However, DB connections do not close properly after tests. Here is an example:
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 error:
django.db.utils.OperationalError: database "test_mydbname" is being accessed by other users
Sqlite error:
sqlite3.OperationalError: database table is locked: test_mydbname
I've tried swapping sync_to_async
with database_sync_to_async
from django-channels, but this didn't change anything.
How can I fix this?
Upvotes: 6
Views: 2150
Reputation: 2408
The issue comes with how your async runloops are interacting with the main thread, handling this yourself can get quite complex.
For testing django-channels
I suggest using pytest
with pytest-asyncio
for testing channels. And of course pytest-django
.
This will provide a few useful tools for testing async code.
@pytest.mark.django_db(transaction=True)
@pytest.mark.asyncio
async def test1():
count = await database_sync_to_async(Book.objects.count)
....
for some examples of how to test channels code take a look here.
Upvotes: 2