如何在Django pytest中使用已有data数据库schema且无需迁移?
问题描述
我为API配置了两个PostgreSQL数据库:
default:对应publicschemadata:对应已有的dataschema
数据库配置如下:
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
相关产品推荐
相关产品推荐

