fix(checkpointer): strip SQLAlchemy dialect prefix before passing to LangGraph

DeerFlow 用同一个 \`postgres_url\` 喂两条路径:
  - SQLAlchemy 引擎(需 \`postgresql+asyncpg://\`)
  - LangGraph AsyncPostgresSaver(psycopg 直连,需 libpq 风格 \`postgresql://\`)

PR2 把 .env / config.example.yaml 默认 URL 改成 \`+asyncpg\` 形态后,LangGraph
saver from_conn_string 会被 psycopg parser 直接抛 ProgrammingError
'missing "=" after "postgresql+asyncpg://..."'。

修:在 async_provider.py 传给 AsyncPostgresSaver 之前用正则剥掉
\`postgresql+\\w+://\` → \`postgresql://\`。一行修复,让同一个 URL 同时满足
SQLAlchemy 和 LangGraph 两条路径。

实测:make dev-daemon 起 gateway 成功,远程 RDS 上 9 张表(DeerFlow 5 +
LangGraph 4)全部 create_all 出来。

Stage 0 PR2 follow-up(不在原 plan task list 内,是 live make dev 触发的)。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1445043649
2026-05-11 17:54:57 +08:00
parent bdef6c6b9f
commit 39f8e117e8
@@ -20,6 +20,7 @@ from __future__ import annotations
import asyncio
import contextlib
import logging
import re
from collections.abc import AsyncIterator
from langgraph.types import Checkpointer
@@ -114,7 +115,14 @@ async def _async_checkpointer_from_database(db_config) -> AsyncIterator[Checkpoi
if not db_config.postgres_url:
raise ValueError("database.postgres_url is required for the postgres backend")
async with AsyncPostgresSaver.from_conn_string(db_config.postgres_url) as saver:
# LangGraph's AsyncPostgresSaver wraps psycopg directly and expects a
# libpq-style conninfo (`postgresql://...`). DeerFlow's own SQLAlchemy
# engine uses the same `postgres_url` but needs the `+asyncpg` dialect
# prefix. Strip the dialect prefix here so the same env var/config
# value satisfies both paths.
lg_conn_str = re.sub(r"^postgresql\+\w+://", "postgresql://", db_config.postgres_url)
async with AsyncPostgresSaver.from_conn_string(lg_conn_str) as saver:
await saver.setup()
yield saver
return