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

pytest-django如何在测试数据库创建完成后注册自定义数据库类型

问题根因

你自定义的django_db_setup没有生效的核心原因是:pytest内置fixture的覆盖规则要求重写的fixture必须放在项目根目录的conftest.py中才会生效,且直接覆盖pytest-django的核心fixture容易出现版本兼容问题,不推荐这么做。
另外你原代码在元类初始化阶段(即模块导入时)就执行数据库操作的设计本身不符合Django最佳实践,模块导入阶段测试数据库还未创建,必然会触发注册失败的问题。

解决方案

第一步:修正字段元类的自动注册逻辑

移除元类中模块导入时的自动注册调用,避免导入阶段就访问数据库:

class FieldMeta(type):
    def __init__(cls, name, bases, clsdict):
        super().__init__(name, bases, clsdict)
        # 删除这行自动调用逻辑
        # cls.register_type()

    # register_type方法其余逻辑保持不变

生产环境可以在Django应用的apps.py的ready钩子中执行注册,保证项目启动、数据库连接初始化完成后再操作:

# your_app/apps.py
from django.apps import AppConfig

class YourAppConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'your_app'

    def ready(self):
        from .fields import FooField
        FooField.register_type()

第二步:配置测试环境全局注册逻辑

不需要重写django_db_setup,直接在项目根目录的conftest.py中新增一个自动执行的会话级fixture,依赖django_db_setup保证测试数据库创建完成后再执行注册:

# 项目根目录conftest.py
import pytest
from your_app.fields import FooField

@pytest.fixture(scope="session", autouse=True)
def register_custom_db_types(django_db_setup, django_db_blocker):
    with django_db_blocker.unblock():
        FooField.register_type()

这个fixture会在整个测试会话启动、测试数据库创建迁移完成后自动执行,所有测试用例都可以直接使用自定义的数据库类型。

可选方案:通过迁移创建自定义类型

如果需要在迁移中固化自定义类型的创建逻辑,可以新增一个空迁移写入类型创建代码,这样不管是生产还是测试环境,执行迁移时都会自动创建foo类型:

  1. 生成空迁移文件
python manage.py makemigrations your_app --empty
  1. 编辑迁移文件内容
from django.db import migrations

def create_foo_type(apps, schema_editor):
    schema_editor.execute("CREATE TYPE foo AS (first integer, second integer);")

def drop_foo_type(apps, schema_editor):
    schema_editor.execute("DROP TYPE foo;")

class Migration(migrations.Migration):
    dependencies = [
        ('your_app', '000x_previous_migration'), # 替换为你的上一个迁移编号
    ]
    operations = [
        migrations.RunPython(create_foo_type, drop_foo_type),
    ]

内容的提问来源于stack exchange,提问作者Alex

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 12:45:06