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

Django迁移可在自定义命令读取但pytest测试中无数据如何解决

解决方法

根因分析

你运行测试时添加的--no-migrations是pytest-django提供的特性,该参数的核心逻辑就是主动禁用迁移加载流程,会把所有INSTALLED_APPS下的迁移模块临时替换为空占位符,因此MigrationLoader无法扫描到任何迁移文件,自然返回空的root nodes列表。

解决方案

方案1:直接移除--no-migrations参数(最简推荐)

MigrationLoader.build_graph()本身只会扫描本地迁移文件构建依赖关系,不会执行任何迁移操作,也不会读写数据库,完全符合你「无需执行migrations即可检测迁移错误」的需求,直接修改测试运行命令即可:

pytest

方案2:兼容其他测试需要--no-migrations的场景

如果你的其他测试确实依赖--no-migrations提升运行速度,可以给迁移校验测试做单独适配:

  1. 首先在pytest.ini中添加自定义标记,区分迁移校验类测试:
[pytest]
DJANGO_SETTINGS_MODULE = django_project.settings
python_files = tests.py test_*.py
markers =
    migration_check: 标记为迁移校验测试,强制加载迁移文件
  1. 给测试函数添加标记,临时关闭迁移禁用逻辑:
import pytest
from django.db.migrations.loader import MigrationLoader
from pytest_django.fixtures import _disable_migrations

@pytest.mark.migration_check
def test_multiple_leaf_nodes_in_migration_graph(settings):
    # 临时恢复迁移加载配置
    if _disable_migrations:
        settings.MIGRATION_MODULES = {}
    
    migration_loader = MigrationLoader(None)
    migration_loader.build_graph()
    # 你的校验逻辑示例
    assert not migration_loader.graph.conflicts, "存在迁移冲突"
    for root_node in migration_loader.graph.root_nodes():
        app_name = root_node[0]
        print(app_name)
  1. 分开执行测试即可:
# 先跑迁移校验(不需要加--no-migrations)
pytest -m migration_check
# 再跑其他业务测试,保留--no-migrations提升速度
pytest -m "not migration_check" --no-migrations

扩展建议

你可以直接扩展该测试的校验逻辑,覆盖更多常见迁移问题,全程不需要执行迁移:

  • 检测是否有未生成的迁移:对比模型状态与迁移快照的差异
  • 检测迁移依赖循环
  • 检测是否包含删除字段、删除表等高危数据操作

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 00:24:01