使用Pytest测试FastAPI接口时,Peewee内存数据库表创建失败
问题原因与解决方案
核心问题
Sqlite的:memory:数据库是每个连接独立实例:你在测试fixture中创建的表仅存在于当前连接的内存实例中,但FastAPI处理请求时会复用原来的全局db实例创建新连接,这个新连接对应全新的内存数据库,自然找不到已创建的表。
你之前尝试的file:foobar_database?mode=memory&cache=shared生成file文件,是因为URI格式错误——正确的纯共享内存URI不会关联实体文件。
解决步骤
1. 使用正确的共享内存数据库URI
用file::memory:?cache=shared创建共享内存数据库,该模式下同一进程内的所有连接共享同一个内存数据库实例,且不会生成任何实体文件。
2. 确保所有模型和全局DB实例指向测试库
你的User模型继承自BaseTable,而BaseTable默认绑定原来的db实例。测试时需要同时更新父类模型和全局DB的数据库指向,避免代码中使用父类或全局DB时连接到旧数据库。
修改后的conftest.py代码
from main import app import pytest from fastapi.testclient import TestClient from peewee import SqliteDatabase from src.db import User, BaseTable, db # 导入BaseTable和全局db实例 MODELS = [User] @pytest.fixture def client(): return TestClient(app) @pytest.fixture(scope='session', autouse=True) def db_test(): # 纯共享内存数据库,无实体文件 test_database = SqliteDatabase('file::memory:?cache=shared', uri=True) # 更新父类BaseTable的数据库元数据,确保所有子类模型复用测试库 BaseTable._meta.database = test_database # 替换全局db实例的数据库指向 db.init(test_database) test_database.connect() test_database.create_tables(MODELS) yield test_database # 清理资源 test_database.drop_tables(MODELS) test_database.close()
额外检查
确保你的注册接口(/register_user)中使用User.create(...)而非直接调用全局db的操作——这样会自动使用User当前绑定的测试数据库实例,避免连接到旧的文件数据库。
内容的提问来源于stack exchange,提问作者MrAsianPepperoni
相关产品推荐
相关产品推荐

