不能用 psycopg2,因其为纯同步驱动,即使套线程池仍阻塞事件循环;必须用 asyncpg + sqlalchemy 2.0 异步引擎,url 必须为 postgresql+asyncpg:// 格式,配合 async_sessionmaker 和 yield 依赖注入确保连接正确管理。

直接用 asyncpg + SQLAlchemy 2.0+ 的异步引擎,别碰 psycopg2 同步驱动封装的“伪异步”方案——FastAPI 的 async 路由里调同步 DB 驱动,等于把协程跑成串行,连接池也白搭。
为什么不能用 psycopg2.connect() 在 FastAPI 里?
psycopg2 是纯同步驱动,即使你用 threadpool_executor 包一层,本质仍是阻塞式 I/O。在 FastAPI 的 async def 路由里调它,Uvicorn worker 会被卡住,高并发下连接堆积、超时频发,错误常表现为:
TimeoutError: [Errno 110] Connection timed out-
RuntimeWarning: coroutine 'AsyncSession.execute' was never awaited(混用 sync/async session) - 明明开了 20 个 uvicorn worker,数据库连接数却只到 5 —— 因为大部分 worker 在等 DB 返回
真正该用的是 asyncpg:原生异步、零拷贝解析、连接复用率高,和 SQLAlchemy 2.0+ 的 create_async_engine 天然契合。
DATABASE_URL 格式必须带 asyncpg 协议前缀
SQLAlchemy 2.0+ 不再自动推断驱动,URL 必须显式声明协议。错写成 postgresql://... 或 postgres://... 会默认走 psycopg2,哪怕你已装 asyncpg 也没用。
正确写法只有这一种:
postgresql+asyncpg://<user>:<password>@<host>:<port>/<db></db></port></host></password></user>
常见翻车点:
- 本地 Docker PostgreSQL 默认端口是
5432,但 URL 里漏写:5432→ 连到 localhost:5432 以外的端口 - 密码含特殊字符(如
@、/)没做 URL 编码 →Invalid URL format - 用
localhost而非host.docker.internal(容器内连宿主 PostgreSQL 时)→ 连不上
Session 管理必须用 async_sessionmaker,且依赖注入要带 async context
别手写 session = AsyncSession(...) 然后 try/finally commit/rollback——容易漏 close,连接池耗尽后所有请求卡死。
标准做法是:
- 定义
AsyncSessionLocal = async_sessionmaker(bind=engine, expire_on_commit=False) - 在依赖函数里用
async with AsyncSessionLocal() as session:确保自动 close - FastAPI 依赖注入必须返回
AsyncGenerator,不能 return session 直接对象
典型依赖写法:
from sqlalchemy.ext.asyncio import AsyncSession
from fastapi import Depends
async def get_db() -> AsyncSession:
async with AsyncSessionLocal() as session:
yield session
注意:yield 是关键。如果写成 return session,session 不会自动关闭,下次调用会拿到一个 stale session。
环境变量别硬编码,.env 文件必须用 python-dotenv 加载
DATABASE_URL 这种敏感配置,写死在代码或 settings.py 里等于裸奔。FastAPI 官方推荐用 python-dotenv 加载 .env:
- 项目根目录建
.env,内容如:DATABASE_URL=postgresql+asyncpg://myuser:mypassword@localhost:5432/mydb
- 在
app/core/config.py里用load_dotenv()+os.getenv("DATABASE_URL") - 确保
.env不提交到 Git(加进.gitignore)
最容易被忽略的一点:Docker 容器内运行时,.env 文件默认不会自动挂载进容器。要用 docker run -v $(pwd)/.env:/app/.env 显式挂载,否则容器里读到的 DATABASE_URL 是空的。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











