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

如何在Django pytest中使用已有data数据库schema且无需迁移?

问题描述

我为API配置了两个PostgreSQL数据库:

  • default:对应public schema
  • data:对应已有的data schema

数据库配置如下:

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.postgresql",
        "OPTIONS": {"options": "-c search_path=public"},
        "NAME": config("DB_NAME", default=""),
        "USER": config("DB_USER_NAME", default=""),
        "PASSWORD": config("DB_PASSWORD", default=""),
        "HOST": config("DB_HOST", default="db"),
        "PORT": config("DB_PORT", default=""),
    },
    "data": {
        "ENGINE": "django.db.backends.postgresql",
        "OPTIONS": {"options": "-c search_path=data"},
        "NAME": config("DB_NAME", default=""),
        "USER": config("DB_USER_NAME", default=""),
        "PASSWORD": config("DB_PASSWORD", default=""),
        "HOST": config("DB_HOST", default="db"),
        "PORT": config("DB_PORT", default=""),
    },
}

通过命令python manage.py inspectdb --database=data > apps/data/models.py生成了models.py,其中Product模型定义如下:

class Product(models.Model):
    id = models.AutoField(primary_key=True)
    ...

    class Meta:
        managed = False
        db_table = "Product"

编写的pytest测试代码:

@pytest.mark.django_db(databases=["default", "data"], transaction=True)
class TestSomeTestAPIView:
    view_name = "some-view-name"

    def test_some_test_name(self, auth_client):
        print(Product.objects.using("data").all())

运行测试时出现错误:"Product" table does not exists,需要在不创建迁移的前提下,正常使用已有的data数据库schema和default数据库schema,解决pytest运行报错问题。


解决方案

1. 明确指定模型的schema表名

虽然data数据库配置了search_path=data,但测试环境中Django可能未正确应用该路径,导致无法找到表。修改Product模型的db_table为带schema的全称:

class Product(models.Model):
    id = models.AutoField(primary_key=True)
    ...

    class Meta:
        managed = False
        db_table = "data.Product"  # 明确指定schema.表名

2. 配置测试数据库不执行迁移

在data数据库的配置中添加TEST选项,禁止pytest自动对该数据库执行迁移操作(因为表是已存在的):

"data": {
    "ENGINE": "django.db.backends.postgresql",
    "OPTIONS": {"options": "-c search_path=data"},
    "NAME": config("DB_NAME", default=""),
    "USER": config("DB_USER_NAME", default=""),
    "PASSWORD": config("DB_PASSWORD", default=""),
    "HOST": config("DB_HOST", default="db"),
    "PORT": config("DB_PORT", default=""),
    "TEST": {
        "MIGRATE": False,  # 禁止对该数据库执行迁移
        "CREATE_DB": False,  # 如果测试复用现有数据库,设置为False;若使用独立测试库则可忽略
    }
}

3. 确保测试数据库存在data schema

pytest-django默认会创建全新的测试数据库,其中可能没有data schema。可以通过fixture在测试会话开始前创建该schema:

import pytest
from django.db import connections

@pytest.fixture(autouse=True, scope="session")
def setup_data_schema():
    # 连接到data数据库,创建data schema(如果不存在)
    with connections["data"].cursor() as cursor:
        cursor.execute("CREATE SCHEMA IF NOT EXISTS data;")
    # 若需要导入测试数据,可在此处执行SQL脚本或数据导入逻辑

4. 使用--reuse-db参数运行pytest

如果不想每次测试都重建数据库,可以添加--reuse-db参数,保留已创建的schema和表:

pytest --reuse-db

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 15:55:54