Files
ZY-Agent/docs/multi-tenant-redesign/03-impl/pr1-postgres-setup.zh-CN.md
T
1445043649 240c6bd0e2 docs(mt): 统一 multi-tenant-redesign 命名约定 + README 补执行层索引
命名统一为 .zh-CN.md 后缀(与既有 17 个文件 + README 一致):
- 03-impl/{pr1-8,STATUS}.md → *.zh-CN.md
- Stage 1 spec 去日期前缀、加 .zh-CN,对齐 01-redesign 语义命名

README.zh-CN.md 修复 4 处不统一:
- 顶部加进度指引(现状只信 STATUS,本文是设计/路线导航)
- §0 文档总图补 03-impl 层 + Stage 1 spec + 命名约定注
- §1 表加 Stage 1 spec 行;新增 §1.1 执行记录层(STATUS + 8 impl note 索引)
- §7 阅读路径首次进项目/Stage 1 均加 STATUS + spec 入口

同步更新所有交叉链接(STATUS/pr/spec 自引用、database-schema-as-built、
根 README_zh.md、Stage 0 master plan);全树相对链接校验可达。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28 10:40:42 +08:00

5.7 KiB
Raw Blame History

PR1 · Postgres 接入 + testcontainers fixture

实现笔记。对应 docs/superpowers/plans/2026-05-10-stage-0-multi-tenant-foundation.md PR1T1.1-T1.10)。

状态:已落地10 commits 提交在 branch feat/stage-0-pr1-postgres-fixture

范围

让 DeerFlow 仓储测试 + dev 部署能跑在 Postgres 上,不切默认 backendPR2 的事)。即:

  • postgres-test optional extraharness + backend)→ testcontainers[postgres] 4.x + 复用现有 postgres extraasyncpg / psycopg / langgraph-checkpoint-postgres
  • tests/fixtures/postgres.py 提供 session 级 postgres_container + 每 test 一个 ephemeral DB 的 postgres_url
  • 4 个 smoke test (tests/test_postgres_smoke.py) 验证 fixture 隔离 + init_engine_from_config 在 PG 上自动建表 + ThreadMetaRepository round-trip
  • docker/docker-compose-dev.yamlpostgres:16-alpine service + healthcheck + named volume
  • scripts/doctor.py 新增 Database sectionsqlite/postgres/memory 三态探测,PG 实连 + version
  • scripts/setup_wizard.py Step 3 之后 inline 加一问 "Use Postgres?",默认 Y
  • .github/workflows/backend-postgres-tests.yml 独立 CI workflow 跑 pytest -m postgres

验收

  • cd backend && uv sync --group dev --extra postgres-test 装 testcontainers 成功
  • pytest -m postgres -v 在本地无 Docker 时全部 SKIPfixture 自动跳过)
  • 全套 pytest tests/ 3085 passed + 23 skipped + 0 failedvs baseline 3086 passed + 18 skippeddiff = 4 新 PG smoke skip + 1 env 相关 live test 偶发 skip
  • docker compose -f docker/docker-compose-dev.yaml config --services 列出 5 services 含 postgresYAML 语法 OK
  • make doctorsqlite 模式)Database section 显示 database backend = sqlite (.deer-flow/data)
  • wizard.writer.build_minimal_config(..., database_backend='postgres') 输出 database: { backend: postgres, postgres_url: $DATABASE_URL }
  • CI workflow backend-postgres-tests 在 PR 提交后跑通——待 PR 上去后验证
  • docker compose up -d postgres + pg_isready live OK——待 docker daemon 起

关键决策(lock 项)

选择 理由
Testcontainers 镜像 postgres:16-alpine 与远程 RDS 同大版本(待 PR 后用 SELECT version() 二次确认)
Test 隔离 per-test database (CREATE/DROP DATABASE) asyncpg 不支持 URL-embedded search_pathper-DB 一次 ~50ms,让 test 代码不感知 schema
Container scope session-scoped per-test container 启动 5-10s 太慢;shared container + per-test DB 是最佳折中
Fixture skip 行为 Docker 不可用时 pytest.skip 而非 error dev 环境无 docker 也能跑其余 3000+ 测试
pytest mark 名 postgres 简短、与 no_auto_user 风格一致
Plugin 注册 pytest_plugins = ["fixtures.postgres"] + sys.path insert 不加 tests/__init__.py 避免影响现有 pytest 发现
CI workflow 拆分 独立 backend-postgres-tests.yml 不拖慢 fast unit test loopfork 不强制承担 docker 开销
doctor PG 检查实现 asyncpg connect() + SELECT version() 比 psycopg sync 更与生产路径对齐(生产用 asyncpg)
setup_wizard 集成 inline 问答(不新建 wizard/steps/database.py 最小改动;后续如需更复杂选项再升级为完整 step 模块

Fixture 用法示例

import pytest

pytestmark = [pytest.mark.postgres, pytest.mark.anyio]


@pytest.fixture
def anyio_backend() -> str:
    return "asyncio"


async def test_my_postgres_thing(postgres_url: str) -> None:
    from deerflow.persistence.engine import close_engine, init_engine

    await init_engine("postgres", url=postgres_url)
    try:
        # ...your test...
        ...
    finally:
        await close_engine()  # important: release connections before fixture teardown

跟进项(不在 PR1 范围)

  • PR2:默认 backend 切 postgresconfig.example.yaml + .env.example + docker-compose gateway depends_on postgres
  • PR1 待 follow-up:本地 docker daemon 起来后跑一次 pytest -m postgres -v 实测;如 PG 大版本不是 16,调 postgres:16-alpine → 对应版本
  • 如果发现 fixture 启动慢导致 CI 时间不可接受,考虑 pytest-postgresql 替代 testcontainers(轻量但需要 GitHub Actions service container 而非 testcontainers daemon

涉及文件

类别 文件
依赖 backend/packages/harness/pyproject.tomlbackend/pyproject.tomlbackend/uv.lock
Fixture backend/tests/fixtures/__init__.pybackend/tests/fixtures/postgres.py
Test backend/tests/test_postgres_smoke.py
Conftest backend/tests/conftest.pypytest_plugins + sys.path
Docker docker/docker-compose-dev.yaml
脚本 scripts/doctor.pyscripts/setup_wizard.pyscripts/wizard/writer.py
CI .github/workflows/backend-postgres-tests.yml

提交记录

10 commits(每条 1 task):

fab85b14 build(deps): add postgres-test optional extra for testcontainers   T1.1
ae4ea46b feat(docker): add postgres service to dev compose                  T1.2
31361e2d test(fixtures): add testcontainers Postgres fixture for Stage 0    T1.3
8f480cd7 test(persistence): postgres smoke tests for init_engine + ThreadMetaRepo  T1.4-T1.6
e6f5ba53 feat(doctor): add Database section probing configured backend      T1.7
eae01901 feat(wizard): add Postgres backend question to setup wizard        T1.8
a33b46b4 ci(postgres): add Postgres workflow running @pytest.mark.postgres tests  T1.9

T1.10 的 commit 是这份 doc 本身。