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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user