我有一个配置了 postgres 数据库的 django 项目。 这是requirements.txt的相关部分:
Django==5.0.1
psycopg2-binary==2.9.9
这里我定义了一个模型:
class Item(models.Model):
name = models.CharField(max_length=100)
还有一个测试用例:
class ItemTestCase(TestCase):
def test_create(self):
asyncio.run(Item.objects.acreate(name="Test"))
self.assertEqual(Item.objects.count(), 1)
问题:
当我使用
python manage.py test
运行测试时 - 测试已通过,但最后我看到一个异常,测试运行程序无法销毁测试数据库。
2024-01-18 19:05:03 django.db.utils.OperationalError: database "test_axpress" is being accessed by other users
2024-01-18 19:05:03 DETAIL: There is 1 other session using the database.
有没有办法确保在拆除数据库之前关闭所有连接?
一种解决方案是使用原始 SQL 删除与 postgresql 的所有连接。
# project/testrunner.py
from django.conf import settings
from django.db import connection
from django.test.runner import DiscoverRunner
default_database = settings.DATABASES["default"]["NAME"]
test_database = f"test_{default_database}"
query = f"""
SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
WHERE pg_stat_activity.datname = '{test_database}'
AND pid <> pg_backend_pid();
"""
class CustomTestRunner(DiscoverRunner):
def teardown_databases(self, old_config, **kwargs):
with connection.cursor() as cursor:
cursor.execute(query)
return super().teardown_databases(old_config, **kwargs)
settings.py
...
TEST_RUNNER = "project.testrunner.CustomTestRunner"