FastAPI + PostgreSQL 实战:从入门到不踩坑,一次讲透

张开发
2026/4/5 21:23:10 15 分钟阅读

分享文章

FastAPI + PostgreSQL 实战:从入门到不踩坑,一次讲透
第一部分为什么是PostgreSQL你可以把PostgreSQL想象成一个“极度守规矩的档案管理员”——数据完整性、ACID、复杂查询支持得滴水不漏。相比MySQL它对JSON、全文检索、地理空间数据的支持更原生而且这几年性能优化得特别猛。最关键的是它和FastAPI的异步生态配合得非常好后面你会体会到。⚙️ 第二部分安装PostgreSQLDocker一键搞定最怕那种“双击安装包一路下一步”然后环境变量配半小时的教程。咱们用Docker干净利落。docker run -d \ --name postgres-demo \ -e POSTGRES_PASSWORDmysecretpassword \ -e POSTGRES_USERmyuser \ -e POSTGRES_DBmydb \ -p 5432:5432 \ postgres:15然后你就可以用任何客户端比如TablePlus或DBeaver连上localhost:5432验证一下。记得密码别写死在代码里后面咱们用环境变量。敲黑板本地开发千万别用root用户上面我特意建了普通用户myuser权限最小化原则。 第三部分FastAPI项目初始化创建一个新目录弄个虚拟环境然后装依赖。这里我推荐两个库✅asyncpg—— PostgreSQL的异步驱动性能爆表。✅databases—— 封装了连接池和查询让你能用async/await执行SQL还支持SQLAlchemy Core可选。当初我图省事直接用了同步的psycopg2结果FastAPI异步线程被阻塞性能直接打骨折。所以一定一定要用异步驱动安装命令pip install fastapi uvicorn databases[asyncpg] python-dotenv 第四部分写代码让FastAPI和PG连上线先建一个.env文件存放敏感信息DATABASE_URLpostgresql://myuser:mysecretpasswordlocalhost/mydb然后写主程序main.pyimport os from fastapi import FastAPI from contextlib import asynccontextmanager from databases import Database from dotenv import load_dotenv load_dotenv() DATABASE_URL os.getenv(DATABASE_URL) database Database(DATABASE_URL) asynccontextmanager async def lifespan(app: FastAPI): await database.connect() # 创建表实际项目用Alembic这里演示直接执行SQL query CREATE TABLE IF NOT EXISTS users ( id SERIAL PRIMARY KEY, username VARCHAR(50) UNIQUE NOT NULL, email VARCHAR(100) UNIQUE NOT NULL ); await database.execute(queryquery) print(数据表创建完成) yield await database.disconnect() app FastAPI(lifespanlifespan) app.get(/users) async def get_users(): query SELECT id, username, email FROM users results await database.fetch_all(queryquery) return [dict(r) for r in results] app.post(/users) async def create_user(username: str, email: str): # 简单的插入实际要加异常处理 query INSERT INTO users(username, email) VALUES (:username, :email) RETURNING id values {username: username, email: email} user_id await database.execute(queryquery, valuesvalues) return {id: user_id, username: username, email: email}启动服务uvicorn main:app --reload。打开http://localhost:8000/docs你就能看到自动生成的API文档试一下POST和GET是不是很爽⚠️ 第五部分那些年我踩过的坑精华 坑1连接被拒绝现象ConnectionRefusedError。大概率是Docker容器端口没映射出来或者PostgreSQL配置只绑定了127.0.0.1。用Docker一定要加-p 5432:5432。另外检查防火墙。 坑2asyncpg.exceptions.InvalidPasswordError密码错误其实很多时候是因为URL格式不对。注意postgresql://user:passhost/db特殊字符要URL编码。 坑3在异步函数里用了同步的psycopg2连接这会导致事件循环阻塞性能急剧下降。解决方案就是全程用asyncpg或databases。 坑4事务忘记commit用database.transaction()上下文管理器最安全async with database.transaction(): await database.execute(query1) await database.execute(query2) # 如果出错自动回滚 坑5连接池耗尽默认连接池大小可能不够高并发时需调整database Database(DATABASE_URL, min_size5, max_size20)

更多文章