如何配置Postgres适配pytest,解决Django项目测试UndefinedTable报错
问题原因
你遇到的UndefinedTable报错本质是pytest运行时,自动创建的Postgres测试库中没有生成对应Django应用的表结构,核心诱因通常为三类:
- 配置的Postgres数据库用户没有创建数据库的权限,pytest-django无法正常初始化测试库
- 运行pytest时添加了
--no-migrations等跳过迁移的参数,表结构未正常生成 settings.py中DATABASES的测试库配置错误,测试运行时读取的是空库
Postgres数据库下pytest的正确配置
- 先在
settings.py中完成数据库的基础配置,可自定义测试库参数:
DATABASES = { "default": { "ENGINE": "django.db.backends.postgresql", "NAME": "正式库名称", "USER": "数据库用户名", "PASSWORD": "数据库密码", "HOST": "127.0.0.1", "PORT": "5432", "TEST": { "NAME": "test_自定义测试库名" # 不填该项则pytest会自动生成默认测试库名 } } }
- 给数据库用户分配创建测试库的权限:
登录Postgres终端执行命令ALTER USER 你的数据库用户名 CREATEDB;;如果不想开放建库权限,也可以提前手动创建上面配置的测试库,给对应用户授予读写权限即可。 - 运行pytest时不要添加跳过迁移的参数,首次运行完成后可以加
--reuse-db参数复用测试库,避免每次运行都重建库提升测试效率。
仅测试时切换为sqlite3的配置方法
有两种常用的配置方案,均不会影响正式环境的Postgres配置:
- 方案1:通过pytest钩子覆盖配置
在项目根目录的conftest.py文件中添加如下代码:
import sys def pytest_sessionstart(session): if "test" in sys.argv: from django.conf import settings settings.DATABASES["default"] = { "ENGINE": "django.db.backends.sqlite3", "NAME": ":memory:", # 用内存数据库测试速度更快,也可指定本地文件路径 }
- 方案2:在settings.py中判断运行环境自动切换
import sys # 检测当前是否为测试运行环境 if "test" in sys.argv or "pytest" in sys.argv[0]: DATABASES = { "default": { "ENGINE": "django.db.backends.sqlite3", "NAME": ":memory:", } } else: # 此处放你原本的正式环境Postgres数据库配置 DATABASES = { "default": { "ENGINE": "django.db.backends.postgresql", # 其余参数保持不变 } }
注意:如果你的项目用到了Postgres独有的字段类型(比如ArrayField、RangeField等),需要确保sqlite3版本在3.9及以上,否则切换为sqlite测试时会出现兼容报错。
内容的提问来源于stack exchange,提问作者EliyaMelamed
相关产品推荐
相关产品推荐

