「FastAPI & SQLAlchemy 实战」系列共 10 篇,从协程基础讲到数据库接口。这是第 8 篇。
结论:SQLAlchemy 用三层完成数据库操作:Engine 管连接,Base 管表结构,Session 管一次会话里的增删改查。
一、ORM 是什么
ORM 把表映射成类、把行映射成对象:Department 类对应 departments 表,一个 Department 对象对应一行记录。好处是屏蔽数据库差异、少写 SQL、类型转换由框架处理。
SQLAlchemy 分两层:Core 提供 SQL 表达式、连接池、方言;ORM 在 Core 之上提供类和对象操作。FastAPI 项目通常直接用 ORM。
二、安装与建库
pip install sqlalchemy pymysql
# 先在 MySQL 建库
CREATE DATABASE fastapi_db CHARACTER SET utf8mb4;
三、Base:所有模型的父类
# base.py
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
SQLAlchemy 2.0 也可以用 class Base(DeclarativeBase): pass,效果一样;本篇沿用文档里的 declarative_base()。
四、模型:字段、外键、关系
# models.py
from sqlalchemy import Column, Integer, String, Date, ForeignKey
from sqlalchemy.orm import relationship
from base import Base
class Department(Base):
__tablename__ = "departments"
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(50), nullable=False, unique=True)
location = Column(String(100))
employees = relationship("Employee", back_populates="department", lazy="selectin")
class Employee(Base):
__tablename__ = "employees"
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(50), nullable=False)
age = Column(Integer)
hire_date = Column(Date)
department_id = Column(Integer, ForeignKey("departments.id"), nullable=False)
department = relationship("Department", back_populates="employees", lazy="joined")
primary_key、nullable、unique 是列约束;ForeignKey 建外键;relationship 让对象可以直接互相访问。
五、Engine 与 Session
# database.py
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
DATABASE_URL = "mysql+pymysql://root:123456@localhost:3306/fastapi_db"
engine = create_engine(
DATABASE_URL,
echo=True, # 开发时打印 SQL,生产关掉
pool_pre_ping=True, # 取连接前先探活
)
SessionLocal = sessionmaker(
bind=engine,
autocommit=False,
autoflush=False,
)
六、建表
# create_tables.py
from base import Base
from database import engine
import models # 必须导入,否则模型没注册到 Base.metadata
def create_table():
Base.metadata.create_all(bind=engine)
if __name__ == "__main__":
create_table()
create_all 只会建不存在的表,不会改已有表结构;生产环境改表要用迁移工具。
七、验证
python create_tables.py
# 在 MySQL 执行
SHOW TABLES; # departments, employees
DESC employees; # 字段、外键、索引
八、常见错误
- 忘了导入模型:
Base.metadata里没有表,create_all什么都不建; - 连接串驱动写错:
mysql+pymysql://不能省; - 生产开
echo=True:SQL 日志刷屏; - 用
create_all改表:它不会加字段,改结构要迁移。
下一篇
表和模型有了,下一篇写 CRUD:增删改查、关联关系、加载策略。
上一篇:请求体、Pydantic 与 APIRouter 路由拆分 | 下一篇:SQLAlchemy CRUD、关联关系与加载策略

AI项目博客







我要看文章