logo

FastAPI 快速开发指南:MySQL 数据库集成实践

作者:c4t2025.09.18 18:04浏览量:0

简介:本文详解 FastAPI 框架下如何高效连接 MySQL 数据库,涵盖环境配置、依赖管理、连接池优化及安全实践,助力开发者快速构建高性能 Web API。

FastAPI 快速开发指南:MySQL 数据库集成实践

在现代化 Web 开发中,FastAPI 以其高性能、易用性和自动生成 API 文档的特性,成为构建 Web API 的热门选择。而 MySQL 作为成熟的开源关系型数据库,凭借其稳定性、事务支持和广泛的社区生态,成为后端数据存储的首选方案。本文将系统阐述如何在 FastAPI 项目中高效集成 MySQL 数据库,从基础配置到高级优化,为开发者提供完整的实践指南。

一、环境准备与依赖管理

1.1 项目初始化

FastAPI 项目通常基于 Python 3.7+ 环境,推荐使用虚拟环境隔离依赖。通过以下命令创建并激活虚拟环境:

  1. python -m venv venv
  2. source venv/bin/activate # Linux/macOS
  3. venv\Scripts\activate # Windows

1.2 依赖安装

核心依赖包括 FastAPI、Uvicorn(ASGI 服务器)和 MySQL 连接驱动。推荐使用 pymysqlmysql-connector-python

  1. pip install fastapi uvicorn pymysql sqlalchemy # SQLAlchemy 用于 ORM

若需异步支持,可安装 asyncpgaiomysql,但需注意 FastAPI 默认同步模型下直接使用 pymysql 更简单。

1.3 数据库配置

在项目根目录创建 .env 文件存储敏感信息(需添加到 .gitignore):

  1. DB_HOST=localhost
  2. DB_PORT=3306
  3. DB_USER=root
  4. DB_PASSWORD=your_password
  5. DB_NAME=fastapi_db

通过 python-dotenv 加载配置:

  1. from dotenv import load_dotenv
  2. import os
  3. load_dotenv()
  4. DB_CONFIG = {
  5. "host": os.getenv("DB_HOST"),
  6. "port": int(os.getenv("DB_PORT")),
  7. "user": os.getenv("DB_USER"),
  8. "password": os.getenv("DB_PASSWORD"),
  9. "database": os.getenv("DB_NAME")
  10. }

二、同步模式下的 MySQL 连接

2.1 直接连接(简单场景)

对于轻量级应用,可直接使用 pymysql 建立连接:

  1. import pymysql
  2. from fastapi import FastAPI
  3. app = FastAPI()
  4. def get_db_connection():
  5. return pymysql.connect(
  6. host=DB_CONFIG["host"],
  7. port=DB_CONFIG["port"],
  8. user=DB_CONFIG["user"],
  9. password=DB_CONFIG["password"],
  10. database=DB_CONFIG["database"],
  11. cursorclass=pymysql.cursors.DictCursor
  12. )
  13. @app.get("/users")
  14. def get_users():
  15. conn = get_db_connection()
  16. try:
  17. with conn.cursor() as cursor:
  18. cursor.execute("SELECT * FROM users")
  19. return cursor.fetchall()
  20. finally:
  21. conn.close()

缺点:每次请求创建新连接,性能低下。

2.2 连接池优化

使用 DBUtilsSQLAlchemy 的连接池提升性能:

  1. from dbutils.pooled_db import PooledDB
  2. pool = PooledDB(
  3. creator=pymysql,
  4. maxconnections=5,
  5. mincached=2,
  6. host=DB_CONFIG["host"],
  7. user=DB_CONFIG["user"],
  8. password=DB_CONFIG["password"],
  9. database=DB_CONFIG["database"]
  10. )
  11. @app.get("/users")
  12. def get_users():
  13. conn = pool.connection()
  14. try:
  15. with conn.cursor() as cursor:
  16. cursor.execute("SELECT * FROM users")
  17. return cursor.fetchall()
  18. finally:
  19. conn.close() # 实际归还到连接池

三、异步模式下的 MySQL 集成

3.1 使用 aiomysql

FastAPI 原生支持异步,搭配 aiomysql 可实现非阻塞 I/O:

  1. import aiomysql
  2. from fastapi import FastAPI, Depends
  3. from contextlib import asynccontextmanager
  4. app = FastAPI()
  5. @asynccontextmanager
  6. async def lifespan(app: FastAPI):
  7. # 初始化连接池
  8. pool = await aiomysql.create_pool(
  9. host=DB_CONFIG["host"],
  10. port=DB_CONFIG["port"],
  11. user=DB_CONFIG["user"],
  12. password=DB_CONFIG["password"],
  13. db=DB_CONFIG["database"],
  14. minsize=5,
  15. maxsize=10
  16. )
  17. async with pool:
  18. app.state.pool = pool
  19. yield
  20. pool.close()
  21. await pool.wait_closed()
  22. app = FastAPI(lifespan=lifespan)
  23. async def get_db():
  24. return app.state.pool.acquire()
  25. @app.get("/users")
  26. async def get_users(db=Depends(get_db)):
  27. async with db as conn:
  28. async with conn.cursor() as cursor:
  29. await cursor.execute("SELECT * FROM users")
  30. return await cursor.fetchall()

3.2 使用 SQLAlchemy 2.0 异步 API

SQLAlchemy 2.0+ 原生支持异步:

  1. from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
  2. from sqlalchemy.orm import sessionmaker
  3. from fastapi import FastAPI, Depends
  4. DATABASE_URL = f"mysql+aiomysql://{DB_CONFIG['user']}:{DB_CONFIG['password']}@{DB_CONFIG['host']}:{DB_CONFIG['port']}/{DB_CONFIG['database']}"
  5. engine = create_async_engine(DATABASE_URL, echo=True)
  6. AsyncSessionLocal = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
  7. async def get_db():
  8. async with AsyncSessionLocal() as session:
  9. yield session
  10. app = FastAPI()
  11. @app.get("/users")
  12. async def get_users(db: AsyncSession = Depends(get_db)):
  13. result = await db.execute("SELECT * FROM users")
  14. return result.scalars().all()

四、安全与最佳实践

4.1 防止 SQL 注入

始终使用参数化查询:

  1. # 错误方式(易受注入攻击)
  2. query = f"SELECT * FROM users WHERE username = '{username}'"
  3. # 正确方式
  4. cursor.execute("SELECT * FROM users WHERE username = %s", (username,))

4.2 敏感数据保护

  • 加密存储密码(使用 bcryptpasslib
  • 限制数据库用户权限(仅授予必要权限)
  • 定期轮换数据库凭证

4.3 性能监控

  • 启用 MySQL 慢查询日志
  • 使用 Prometheus + Grafana 监控 API 响应时间
  • 对高频查询添加缓存(如 Redis

五、完整项目示例

5.1 项目结构

  1. fastapi_mysql/
  2. ├── main.py # 入口文件
  3. ├── models.py # 数据模型
  4. ├── schemas.py # Pydantic 模型
  5. ├── database.py # 数据库连接
  6. ├── .env # 环境变量
  7. └── requirements.txt

5.2 核心代码

database.py:

  1. from sqlalchemy import create_engine
  2. from sqlalchemy.orm import sessionmaker
  3. from .config import settings
  4. SQLALCHEMY_DATABASE_URL = f"mysql+pymysql://{settings.DB_USER}:{settings.DB_PASSWORD}@{settings.DB_HOST}:{settings.DB_PORT}/{settings.DB_NAME}"
  5. engine = create_engine(SQLALCHEMY_DATABASE_URL)
  6. SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
  7. def get_db():
  8. db = SessionLocal()
  9. try:
  10. yield db
  11. finally:
  12. db.close()

main.py:

  1. from fastapi import FastAPI, Depends
  2. from sqlalchemy.orm import Session
  3. from .database import get_db
  4. from .models import User
  5. from .schemas import UserCreate
  6. app = FastAPI()
  7. @app.post("/users/")
  8. def create_user(user: UserCreate, db: Session = Depends(get_db)):
  9. db_user = User(**user.dict())
  10. db.add(db_user)
  11. db.commit()
  12. db.refresh(db_user)
  13. return db_user
  14. @app.get("/users/{user_id}")
  15. def read_user(user_id: int, db: Session = Depends(get_db)):
  16. return db.query(User).filter(User.id == user_id).first()

六、部署建议

  1. 容器化部署:使用 Docker 封装应用与 MySQL 服务

    1. FROM python:3.9-slim
    2. WORKDIR /app
    3. COPY . .
    4. RUN pip install -r requirements.txt
    5. CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
  2. 生产环境优化

    • 启用 Gzip 压缩
    • 配置 HTTPS
    • 使用连接池大小适配并发量
  3. 扩展方案

    • 读写分离(主从架构)
    • 分库分表(如使用 Vitess

总结

FastAPI 与 MySQL 的集成可灵活适配从简单 CRUD 到高并发场景的需求。开发者应根据项目规模选择同步/异步模式,合理配置连接池,并始终遵循安全最佳实践。通过 SQLAlchemy 等 ORM 工具,可进一步提升开发效率与代码可维护性。实际项目中,建议结合 CI/CD 流水线实现自动化测试与部署,确保系统稳定性。

相关文章推荐

发表评论