Files
writer-work-flow/apps/api/tests/test_chain_deps.py
Yaojia Wang b5002a9864 fix(chain): checkpointer 连接串剥离 SQLAlchemy 驱动后缀
多章链 job 一发起即 failed(exc_type=ProgrammingError)。根因:runtime
checkpointer 工厂把 settings 的 sync URL `postgresql+psycopg://…` 原样喂给
`AsyncPostgresSaver.from_conn_string`,psycopg 不识别 `+psycopg` 方言段 →
`ProgrammingError: missing "=" …`,链在打开 saver 时即崩。

E2E 用 MemorySaver 覆盖 get_checkpointer_factory,从不走真 conn string,故此
路径无回归保护、bug 未被测出(迁移 d3e4f5a6b7c8 里 `_psycopg_conn_string` 已
正确剥离,runtime 缝漏了同款处理)。

修复:chain_deps 加 `_libpq_conn_string()`,剥离 `+psycopg`/`+asyncpg` 还原为
标准 libpq 串后再交 from_conn_string。+ 单测 test_chain_deps.py(3 参数化用例)。
已直连真 pg 复验:saver.aget OK,ProgrammingError 消除。
2026-06-24 12:40:40 +02:00

43 lines
1.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""chain_deps._libpq_conn_string 单测——剥离 SQLAlchemy 驱动后缀(回归)。
bugruntime checkpointer 工厂曾把 `postgresql+psycopg://…`settings 的 sync URL
原样喂给 `AsyncPostgresSaver.from_conn_string`psycopg 不识别 `+psycopg` 方言段 →
`ProgrammingError: missing "=" …` → 多章链 job 直接 failed。E2E 用 MemorySaver 覆盖,
从不走真 conn string故此路径无回归保护。本用例锁住「剥离后缀」语义。
"""
from __future__ import annotations
import pytest
from ww_api.services import chain_deps
class _StubSettings:
def __init__(self, url: str) -> None:
self.database_url_sync = url
@pytest.mark.parametrize(
("raw", "expected"),
[
(
"postgresql+psycopg://writer:writer@localhost:5432/writer",
"postgresql://writer:writer@localhost:5432/writer",
),
("postgresql+asyncpg://u:p@h:5432/db", "postgresql://u:p@h:5432/db"),
("postgresql://u:p@h:5432/db", "postgresql://u:p@h:5432/db"),
],
)
def test_libpq_conn_string_strips_driver_suffix(
monkeypatch: pytest.MonkeyPatch, raw: str, expected: str
) -> None:
# Arrange
monkeypatch.setattr(chain_deps, "get_settings", lambda: _StubSettings(raw))
# Act
result = chain_deps._libpq_conn_string()
# Assert
assert result == expected
assert "+psycopg" not in result
assert "+asyncpg" not in result