fastapi: 第二十五章:用sqlalchemy访问mysql数据库
一,创建相应的数据库:

二,安装sqlalchemy和mysql驱动
$ pip install sqlalchemy aiomysql pydantic
三,代码
database.py
# app/core/database.py
from sqlalchemy.orm import sessionmaker, declarative_base
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, async_sessionmaker
# 数据库连接URL
# 格式:数据库类型+驱动://用户名:密码@主机:端口/数据库名
DATABASE_URL = "mysql+aiomysql://root:rootpassword@localhost:3306/media_bank"
# 创建异步引擎
# engine 是数据库连接的核心对象,负责管理连接池
engine = create_async_engine(
DATABASE_URL,
echo=True, # 打印SQL语句,方便调试,生产环境应设为False
pool_size=10, # 连接池大小
max_overflow=20 # 连接池溢出后的最大连接数
)
# 创建会话工厂
# AsyncSessionLocal 可以创建数据库会话对象
AsyncSessionLocal = async_sessionmaker(engine, expire_on_commit=False)
# 创建模型基类
# 所有的数据模型都要继承这个类
Base = declarative_base()
# 获取数据库会话的依赖函数
async def get_db():
async with AsyncSessionLocal() as session:
try:
yield session # 把会话交给接口使用
await session.commit() # 正常结束则提交事务
except Exception:
await session.rollback() # 发生异常则回滚
raise
finally:
await session.close() # 关闭会话
model的基类,包含公共字段
from app.core.database import Base
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
from datetime import datetime
from sqlalchemy import func
# 定义一个基类,包含公共字段
class BaseModel(Base):
__abstract__ = True # 这个类不会创建表,只是用来继承
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True,comment='主键')
created_at: Mapped[datetime] = mapped_column(server_default=func.now(),comment="创建时间")
updated_at: Mapped[datetime] = mapped_column(server_default=func.now(),onupdate=func.now(), comment="最新修改时间")
产品类:
# app/models/products.py
from app.core.basemodel import BaseModel
from sqlalchemy.orm import Mapped, mapped_column
from sqlalchemy import String
# 商品模型
class Product(BaseModel):
__tablename__ = "products"
name: Mapped[str] = mapped_column(String(100),server_default="''", comment='商品名称')
price: Mapped[int] = mapped_column(comment='价格')
stock: Mapped[bool] = mapped_column(comment='库存')
路由中访问model类:
# app/api/products.py
from fastapi import APIRouter, Request, Depends
from app.core.database import get_db
from app.core.logger import logger
from app.models.products import Product
from app.utils.log_util import get_query_param
from app.utils.response import success,fail
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.future import select # 2.0 推荐使用 select 语法
import app.models
router = APIRouter(prefix="/products", tags=["商品管理"])
@router.get("/all")
async def get_all_products(request: Request, db: AsyncSession = Depends(get_db)):
# 异步写法不能直接用 db.query(),必须用 select
skip = 0
limit = 10
stmt = select(Product).offset(skip).limit(limit)
result = await db.execute(stmt) # 必须 await 数据库 I/O
prods = result.scalars().all()
res = {
"list": prods,
}
return success(data=res)
说明:手动创建数据表,并插入几条测试数据
四,测试效果 :

浙公网安备 33010602011771号