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

pytest环境下测试数据库执行alembic upgrade不生效问题求助

问题排查与解决方案

一、Alembic迁移未执行的问题

你可以按照以下顺序排查修复:

  • 先检查代码语法错误:你贴出的代码里导入模块段末尾有一个多余的单独反引号,如果实际运行的代码里也存在该符号,会导致顶层代码执行中断,迁移逻辑直接不会运行,先删除该多余符号。
  • 确认Alembic配置路径正确:你直接传入Config("alembic.ini")读取配置,当pytest运行的工作目录不是项目根目录时,会找不到alembic.ini文件和迁移脚本文件夹,导致迁移静默失败。可以修改为读取绝对路径:
    import os
    # 路径根据你自己的项目结构调整,这里示例取当前测试文件上两级目录作为项目根目录
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    alembic_cfg = Config(os.path.join(BASE_DIR, "alembic.ini"))
    # 手动指定迁移脚本文件夹位置,避免alembic找不到
    alembic_cfg.set_main_option('script_location', os.path.join(BASE_DIR, "alembic"))
    alembic_cfg.set_main_option('sqlalchemy.url', str(TEST_DB_URL))
    
  • 增加错误捕获排查迁移失败原因:目前你没有对迁移操作加异常捕获,就算迁移执行报错也不会抛出,你可以加异常打印确认具体问题:
    try:
        alembic.command.upgrade(alembic_cfg, "head")
        print("迁移执行成功")
    except Exception as e:
        print(f"迁移执行失败,错误信息:{e}")
        raise
    
  • 确认TEST_DB_URL取值正确:你代码里的DATABASE_URL没有显示导入逻辑,如果该变量本身取值错误,会导致拼接后的测试库链接虽然可以正常建库,但Alembic连接时出现权限、编码类问题导致迁移失败,你可以打印TEST_DB_URL确认格式符合postgresql链接规范。

二、接口返回404的问题

排查方向如下:

  • 确认FastAPI实例app导入正确:如果你测试文件里导入的app不是你实际挂载了/register路由的实例,自然会返回404。
  • 确认路由地址匹配:检查你的/register接口是否有统一前缀,比如你给所有接口加了/api前缀的话,测试请求地址应该改为/api/register,同时确认接口的请求方法确实是POST。
  • 你可以在测试代码里打印app.routes查看所有已注册的路由,确认/register路由确实存在。

额外优化建议

你目前把建库、删库、迁移的逻辑写在测试文件顶层,只会在第一次导入测试文件时执行,如果你有多个测试文件或者多次运行测试,会出现逻辑异常。建议把这部分逻辑挪到session级别的fixture里,示例如下:

@pytest.fixture(scope="session")
def init_test_db():
    if database_exists(TEST_DB_URL):
        drop_database(TEST_DB_URL)
    create_database(TEST_DB_URL)
    # 执行Alembic迁移
    import os
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    alembic_cfg = Config(os.path.join(BASE_DIR, "alembic.ini"))
    alembic_cfg.set_main_option('script_location', os.path.join(BASE_DIR, "alembic"))
    alembic_cfg.set_main_option('sqlalchemy.url', str(TEST_DB_URL))
    alembic.command.upgrade(alembic_cfg, "head")
    yield
    # 测试结束后自动删除测试库
    drop_database(TEST_DB_URL)

# 让connection fixture依赖初始化fixture,保证测试运行前库已经初始化完成
@pytest.fixture(scope='session')
def connection(init_test_db):
    connection = engine.connect()
    yield connection
    connection.close()

内容的提问来源于stack exchange,提问作者Shiladitya Bose

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 19:45:03