OpenHands 源码解析 · 第 13 讲
OpenHands 源码解析系列 第 13 讲:数据库设计与 ORM 层 基于 OpenHands 源码 · 2026-08-09 一、数据库架构概览 OpenHands 的数据库层是 V1 App Server 的核心基础设施。它同时支持 PostgreSQL (生产环境)和 SQLite (本地开发),通过 SQLAlchemy 2.0 的 DeclarativeBase 构建了完整的 ORM 抽象。数据库层的设计围绕三个核心目标: 🔹 双引擎支持 :同步 pg8000 + 异步 asyncpg,同一套模型两种驱动 🔹 请求级会话 :每个 HTTP 请求一个 AsyncSession,自动 commit/rollback 🔹 渐进式迁移 :Alembic 14 次迁移,从 V0 到 V1 平滑演进 📦 核心文件 app_server/services/db_session.py — DbSessionInjector 配置与引擎管理 app_server/utils/sql_utils.py — Base 类与 TypeDecorator 工具 app_server/services/db_session_injector.py — FastAPI DI 桥接 db/ssl.py — SSL 模式标准化 app_lifespan/alembic/ — 14 次迁移脚本 二、DbSessionInjector:数据库配置的集中化管理 OpenHands 没有使用传统的 SQLAlchemy.create_engine() 裸调用,而是将所有数据库配置封装在 DbSessionInjector 中。这个类继承自 Pydantic BaseModel 和自定义的 Injector[AsyncSession] 接口,实现了配置校验、引擎创建、会话管理的三位一体。 2.1 配置模型与 Pydantic 校验 📄 app_server/services/db_session.py (第 29-52 行) class DbSessionInjector(BaseModel, Injector[AsyncSession]): persistence_dir: Path host: str | None = None port: int | None = None name: str | None = None user: str | None = None password: SecretStr | None = None echo: bool = False pool_size: int = 25 max_overflow: int = 10 pool_recycle: int = 1800 pool_use_lifo: bool = True gcp_db_instance: str | None = None gcp_project: str | None = None gcp_region: str | None = None ssl_mode: str | None = None # Private attrs _engine: Engine | None = PrivateAttr(default=None) _async_engine: AsyncEngine | None = PrivateAttr(default=None) _session_maker: sessionmaker | None = PrivateAttr(default=None) _async_session_maker: async_sessionmaker | None = PrivateAttr(default=None) _gcp_connector: Any = PrivateAttr(default=None) 设计要点: 🔹 SecretStr 保护密码字段,序列化时自动脱敏 🔹 PrivateAttr 存放运行时引擎实例,不参与 Pydantic 序列化 🔹 连接池默认 25 + 10 overflow,1800 秒回收,LIFO 策略(减少冷启动延迟) 🔹 GCP Cloud SQL 专用字段支持 Google Cloud 托管数据库 2.…