Django的connection_created信号在pytest+PostgreSQL测试环境下引发RuntimeWarning问题求助
我最近在开发一个Django应用的通知订阅功能,需求是让用户可以订阅一种或多种通知类型。每种通知类型都有自定义的业务逻辑,所以我给每个通知类型都写了单独的类,同时用一个单例类NotificationTypeSingleton来统一收集所有通知类型的名称、描述等元数据。
为了在数据库中持久化支持的通知类型,以及存储用户和通知类型之间的多对多订阅关系,我设计了两张表:
NotificationType表:存储通知类型的元数据(名称、描述、是否激活等)- 用户与通知类型的关联表:记录用户的订阅关系
为了让代码中定义的通知类型变更能自动同步到数据库,我使用了Django的connection_created信号,在数据库连接建立时自动创建或更新NotificationType记录,同时将不再使用的通知类型标记为 inactive,最后更新单例的注册表。我的信号代码如下:
from django.db.backends.signals import connection_created from django.db.backends.sqlite3.base import ( DatabaseWrapper as SQLiteDatabaseWrapper, ) from django.db.backends.postgresql.base import ( DatabaseWrapper as PostgresDatabaseWrapper, ) from django.dispatch import receiver from notification_type_singleton import NotificationTypeSingleton from models import NotificationType @receiver(connection_created, sender=SQLiteDatabaseWrapper) @receiver(connection_created, sender=PostgresDatabaseWrapper) def create_or_update_notification_type(sender, **kwargs): exiting_ids = [] for _, notification_type in ( NotificationTypeSingleton._data.items() ): notification, _ = NotificationType.objects.update_or_create( name=notification_type.name, defaults={ 'description': notification_type.description, 'is_active': True, }, ) exiting_ids.append(notification.id) # 标记数据库中不再使用的通知类型为非激活 NotificationType.objects.exclude(id__in=exiting_ids).update(is_active=False) # 更新单例注册表为数据库中激活的通知类型 NotificationTypeSingleton._registry = { notification.name: notification for notification in NotificationType.objects.filter(is_active=True) }
这段代码在本地用python manage.py runserver启动应用时完全正常,但当我用pytest配合PostgreSQL进行测试时,虽然信号能正常触发,但会抛出以下警告:
RuntimeWarning: Normally Django will use a connection to the 'postgres' database to avoid running initialization queries against the production database when it's not needed (for example, when running tests). Django was unable to create a connection to the 'postgres' database and will use the first PostgreSQL database instead.
如果我注释掉信号中所有执行数据库查询的代码,这个警告就会消失。我查了Django官方文档,里面提到connection_created信号的用途就是执行SQL后端的连接后命令,我觉得自己的用法是符合预期场景的,但测试时却出现了这个副作用。
想问一下有没有其他开发者遇到过类似的问题?或者有没有办法在测试环境下避免这个警告?
内容来源于stack exchange

