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

如何用pytest-postgresql复用Docker化PostgreSQL作为测试模板数据库?

解决pytest-postgresql复用模板数据库的完整示例

前提准备

  • 确保Docker化的PostgreSQL已启动,提前创建好带目标Schema的模板数据库(比如命名为test_template),执行以下SQL将其标记为可复用模板:
ALTER DATABASE test_template IS_TEMPLATE = true;

配置conftest.py

在项目根目录创建conftest.py,配置noprocess工厂连接现有Docker数据库,同时手动控制测试库从指定模板创建:

import pytest
from pytest_postgresql.factories import postgresql_noprocess

# 配置noprocess工厂,连接到Docker中PostgreSQL的管理库(用于创建/删除测试库)
postgres_admin = postgresql_noprocess(
    dbname="postgres",
    user="your_db_user",
    password="your_db_password",
    host="localhost",  # Docker映射的主机地址
    port="5432"        # Docker映射的端口
)

# 自定义fixture:从模板创建独立测试库,测试后自动清理
@pytest.fixture(scope="function")
def postgres_test_db(postgres_admin):
    # 生成唯一测试库名,避免并行测试冲突
    test_db_name = f"test_run_{id(postgres_admin)}"
    
    # 从预定义模板创建新测试库
    with postgres_admin.cursor() as cur:
        cur.execute(f"CREATE DATABASE {test_db_name} TEMPLATE test_template;")
        postgres_admin.commit()
    
    # 创建连接到新测试库的客户端
    test_client = postgresql_noprocess(
        dbname=test_db_name,
        user="your_db_user",
        password="your_db_password",
        host="localhost",
        port="5432"
    )
    
    yield test_client
    
    # 测试完成后清理:先终止连接,再删除数据库
    test_client.close()
    with postgres_admin.cursor() as cur:
        cur.execute(f"""
            SELECT pg_terminate_backend(pid)
            FROM pg_stat_activity
            WHERE datname = '{test_db_name}' AND pid <> pg_backend_pid();
        """)
        cur.execute(f"DROP DATABASE {test_db_name};")
        postgres_admin.commit()

测试用例示例

直接使用自定义fixture编写测试,验证模板Schema已被复用:

def test_existing_schema(postgres_test_db):
    cursor = postgres_test_db.cursor()
    # 查询模板中已创建的表,确认测试库继承了Schema
    cursor.execute("SELECT table_name FROM information_schema.tables WHERE table_schema = 'public';")
    tables = cursor.fetchall()
    assert len(tables) > 0  # 验证模板表已存在
    cursor.close()

错误原因说明

你之前遇到的database already exists问题,是因为默认postgresql工厂会自动尝试创建{dbname}_tmpl作为模板库,再基于它生成测试库。但我们已经提前准备了自定义模板库,因此需要跳过自动生成_tmpl的逻辑,手动控制测试库的创建流程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 10:57:23