You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django的connection_created信号在pytest+PostgreSQL测试环境下引发RuntimeWarning问题求助

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 06:54:29