文章目录
- 一、代码全流程(数字顺序,核心步骤)
- 二、核心代码逐行解析
-
- 模块1:基础配置(导入+创建应用)
- 模块2:数据库核心配置(引擎+模型)
- [模块3:自动建表 + 数据库依赖(核心工具)](#模块3:自动建表 + 数据库依赖(核心工具))
- 三、重点:增删改查接口逐行解析
- 四、总结
一、代码全流程(数字顺序,核心步骤)
代码内容:
python
from fastapi import FastAPI, Depends, HTTPException
from pydantic import BaseModel
from starlette import status
# 创建FastAPI对象
app = FastAPI()
# 工具模块
# 工具模块通常写一些 创建数据库引擎 获取Session....
from datetime import datetime
from sqlalchemy import DateTime, func, String, Float, Select, Insert, Delete, select, ForeignKey
from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker, AsyncSession
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
# 链接数据库的url地址
DATABASE_URL = "mysql+aiomysql://root:root@localhost:3306/fastapi_review?charset=utf8"
# 1. 异步数据库引擎
'''
启用 SQL 日志:echo=True 会在控制台输出执行的 SQL 语句,便于调试
连接池配置:
pool_size=10:连接池基础大小为 10 个连接
max_overflow=20:最大溢出连接数为 20(即最多可有 30 个并发连接)
'''
engine = create_async_engine(DATABASE_URL, echo=True, pool_size=10, max_overflow=20)
# 2. 建立模型映射。不成文的规定(阿里)
class Base(DeclarativeBase):
# 创建时间
create_time: Mapped[datetime] = mapped_column(DateTime, default=datetime.now)
# 更新时间
update_time: Mapped[datetime] = mapped_column(DateTime,
default=datetime.now,
onupdate=func.now(),
insert_default=func.now()
)
class Department(Base):
__tablename__ = "t_department"
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True, name="department_id",
comment="部门ID")
name: Mapped[str] = mapped_column(String(20), nullable=False, name="department_name",
comment="部门名称")
location: Mapped[str] = mapped_column(String(100), nullable=False, name="department_location",
comment="部门位置")
def __str__(self):
return f"Department(id={self.id}, name={self.name}, location={self.location})"
class User(Base):
__tablename__ = "t_user"
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True, name="user_id",
comment="用户ID")
name: Mapped[str] = mapped_column(String(20), nullable=False, name="user_name",
comment="用户名称")
password: Mapped[str] = mapped_column(String(20), nullable=False, name="user_password",
comment="用户密码")
salary: Mapped[float] = mapped_column(Float(6, 2), nullable=False, name="user_salary",
comment="用户薪水")
birthday: Mapped[datetime] = mapped_column(DateTime, nullable=False, name="user_birthday",
comment="用户出生日期")
department_id: Mapped[int] = mapped_column(ForeignKey("t_department.department_id"),
nullable=False, name="department_id",
comment="部门ID")
def __str__(self):
return f"User(id={self.id}, name={self.name}, password={self.password}, salary={self.salary}, birthday={self.birthday}, department_id={self.department_id})"
# 3. 创建表
async def create_tables():
# 获取异步引擎,创建事务 - 建表
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all) # Base 模型类的元数据创建
# 事件监听器。事件 监听器(容器监听)当容器一启动,创建事件对象("startup")。就会动态调用此函数
@app.on_event("startup")
async def init():
await create_tables()
# 4. 异步Session工厂
AsyncSessionLocal = async_sessionmaker(bind=engine, class_=AsyncSession, expire_on_commit=False)
# 5.创建依赖项
async def get_session():
async with AsyncSessionLocal() as session:
try:
yield session
await session.commit()
except Exception as e:
await session.rollback()
finally:
await session.close()
@app.get("/users")
async def get_user_list(session: AsyncSession = Depends(get_session)):
"""
查询所有用户
:param session:
:return:
"""
# 1.生成语句对象
stmt = Select(User)
# 2.执行语句对象 发SQL
result = await session.execute(stmt)
# 3.获取结果
user_list = result.scalars().all()
return user_list
# 条件查询
@app.get("/users/")
async def get_user_by_name(name: str, session: AsyncSession = Depends(get_session)):
"""
根据用户名称精确查询用户列表
:param name: 用户名称
:param session: 会话
:return: 用户列表
"""
stmt = Select(User).where(User.name == name)
result = await session.execute(stmt)
user_list = result.scalars().all()
return user_list
@app.get("/users/like/")
async def get_user_like_name(name: str, session: AsyncSession = Depends(get_session)):
"""
根据用户名称模糊查询用户列表
:param name: 用户名称
:param session: 会话
:return: 用户列表
"""
# user_name like '%z%'
stmt = Select(User).where(User.name.like(f"%{name}%"))
result = await session.execute(stmt)
user_list = result.scalars().all()
return user_list
# http://localhost:8888/users/in/?ids=2,4 查询参数
@app.get("/users/in/")
async def get_user_in_ids(ids: str, session: AsyncSession = Depends(get_session)):
# ["2","4"] ------> [2,4]
id_list = ids.split(",")
id_final_list = []
for item in id_list:
temp = int(item)
id_final_list.append(temp)
# 可以使用lambda函数(匿名函数)
# map(int, id_list)
# select * from t_user where user_id in (2,4)
stmt = Select(User).where(User.id.in_(id_final_list))
result = await session.execute(stmt)
user_list = result.scalars().all()
return user_list
@app.get("/users/between/{min_salary}/{max_salary}")
async def get_user_between_salary(min_salary: float,
max_salary: float,
session: AsyncSession = Depends(get_session)):
"""
根据用户薪资范围查询用户列表
:param min_salary: 薪资最小薪资
:param max_salary: 薪资最大薪资
:param session: 会话
:return: 用户列表
"""
# user_name like '%z%'
stmt = Select(User).where(User.salary.between(min_salary, max_salary))
result = await session.execute(stmt)
user_list = result.scalars().all()
return user_list
@app.get("/users/{id}")
async def get_user_by_id(id: int,
session: AsyncSession = Depends(get_session)):
"""
根据用户薪资范围查询用户列表
:param min_salary: 薪资最小薪资
:param max_salary: 薪资最大薪资
:param session: 会话
:return: 用户列表
"""
# user_name like '%z%'
# stmt = Select(User).where(User.id == id)
# result = await session.execute(stmt)
# user = result.scalar()
user = await session.get(User, id)
return user
@app.get("/users/page/{page_no}/{page_size}")
async def get_user_by_id(page_no: int, page_size: int,
session: AsyncSession = Depends(get_session)):
"""
根据用户薪资范围查询用户列表
:param min_salary: 薪资最小薪资
:param max_salary: 薪资最大薪资
:param session: 会话
:return: 用户列表
"""
stmt = Select(User).offset((page_no - 1) * page_size).limit(page_size)
result = await session.execute(stmt)
user_list = result.scalars().all()
return user_list
# 利用Pydantic验证模型数据
class UserRequest(BaseModel):
name: str
password: str
salary: float
birthday: datetime
class UserUpdate(BaseModel):
id: int
name: str
password: str
salary: float
birthday: datetime
# 添加用户
@app.post("/users")
async def add_user(user: UserRequest, session: AsyncSession = Depends(get_session)):
# if user is None:
# # 抛出异常
# raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="用户信息不能为空")
# stmt = Insert(User).values(**user.__dict__)
# await session.execute(stmt)
# # await session.commit()
# 另外一种实现方式:将pydantic类型(UserRequest)转换成数据库类型(User)对象
name = user.name
password = user.password
salary = user.salary
birthday = user.birthday
# 封装成User类型的对象
user_object = User(name=name, password=password, salary=salary, birthday=birthday)
session.add(user_object)
return {
"code": 200,
"message": "添加成功"
}
# 删除用户,根据用户编号删除用户
@app.delete("/users/{id}")
async def delete_user(id: int, session: AsyncSession = Depends(get_session)):
# stmt = Select(User).where(User.id == id)
# result = await session.execute(stmt)
#
# # 查询了一个对象,要么就是None,要么就一个对象
# user = result.scalar_one_or_none()
#
# if user is None:
# raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST,detail="用户不存在")
# 1. 有时候我们做删除还需要判断该用户是否有关联对象,如果存在关联对象,那么势必需要先处理关系后再做删除
# 2. 真正的开发中删除操作基本都是逻辑删除(只是修改状态 is_deleted = True),不会物理删除。
stmt = Delete(User).where(User.id == id)
await session.execute(stmt)
await session.commit()
return {
"code": 200,
"message": "删除成功"
}
@app.put("/users/{id}")
async def update_user(id: int, user_request: UserRequest,
session: AsyncSession = Depends(get_session)):
"""
:param id: 用户编号
:param user_request: 从前端传递的请求体数据。这些数据是全新数据
:param session:
:return:
"""
# TODO 1. 根据id查询用户得到user_object
stmt = Select(User).where(User.id == id)
result = await session.execute(stmt)
user = result.scalar_one_or_none()
# TODO 将新数据(user_request)中的各个属性值覆盖掉user_object对象中的属性
user.name = user_request.name
user.password = user_request.password
user.salary = user_request.salary
user.birthday = user_request.birthday
return {
"code": 200,
"message": "修改成功"
}
class DepartmentRequest(BaseModel):
name: str
location: str
class DepartmentAddRequest(DepartmentRequest):
users: list[UserRequest]
# TODO添加部门的同时,初始化用户数据
@app.post("/departments/")
async def add_department(department_add_request: DepartmentAddRequest,
session: AsyncSession = Depends(get_session)):
if department_add_request is None:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="部门信息不能为空")
if department_add_request.users is None:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="用户信息不能为空")
# 1. 先添加部门
# session.add(depart) → 对象进入 pending 状态,此时 depart.id 是 None
# session.flush()(commit() 内部会先 flush)→ SQLAlchemy 发 INSERT SQL,数据库返回自增主键,SQLAlchemy 把这个 id 回填到 depart.id 上
# session.commit() → 真正提交事务
depart = Department(name=department_add_request.name, location=department_add_request.location)
session.add(depart)
await session.commit()
# ???为什么这里需要刷新?
# refresh() 的作用是 重新发一条 SELECT 语句,把数据库里这一行的全部字段重新加载回对象,主要用来同步:
#
# 数据库端计算的字段(如 server_default、触发器、func.now() 写进 DB 的默认值)
# 并发场景下可能被别人改过的字段
# 被 expire 掉的属性
# 对"只拿自增 id"这个需求来说,refresh 其实是多余的。
session.refresh(depart)
# 2. 遍历用户列表,用户的department_id设置值,添加用户
for user in department_add_request.users:
user = User(name=user.name,
password=user.password,
salary=user.salary,
birthday=user.birthday,
department_id=depart.id)
session.add(user)
# await session.commit()
return {
"code": 200,
"message": "添加成功"
}
# TODO 删除部门。如果这个部门有员工,那能不能删的问题?根据需求来做
# 如果这个部门有员工,那么将这些员工的department_id设置为None,然后再删除部门
class UserDepartmentResponse(BaseModel):
id: int
name: str
password: str
salary: float
birthday: datetime
department_id: int
department_name: str
department_location: str
# TODO 根据部门名称查询该部门下的员工以及部门信息
@app.get("/api/users/{name}")
async def get_users_by_department_name(name: str, session: AsyncSession = Depends(get_session)):
stmt = select(User,Department).join(Department,User.department_id == Department.id).where(
Department.name
== name)
# result内部持有一个什么类型的对象?元组
result = await session.execute(stmt)
# 此处不用再调用scalars()方法,因为已经查询到了元组
user_list = result.all()
user_department_list = []
for item in user_list:
user_obj = item[0]
department_obj = item[1]
user_department_response = UserDepartmentResponse(
id=user_obj.id,
name=user_obj.name,
password=user_obj.password,
salary=user_obj.salary,
birthday=user_obj.birthday,
department_id=user_obj.department_id,
department_name=department_obj.name,
department_location=department_obj.location
)
user_department_list.append(user_department_response)
# # 根据部门名称查询部门
#
# # 组装数据(list[UserDepartmentResponse])
# user_department_list = []
return {
"code": 200,
"message": "查询成功",
"data": user_department_list
}
# TODO 根据用户名称查询该用户所在部门
@app.get("/departments/{name}")
async def get_department_by_user_name(name:str,
session: AsyncSession = Depends(get_session)):
# 优缺点:性能稍好,但是如果连接的表太多其实也会有性能损耗
stmt = select(Department).join(User, Department.id == User.department_id).where(User.name == name)
result = await session.execute(stmt)
department = result.scalar_one_or_none()
return {
"code": 200,
"message": "查询成功",
"data": department
}
# 先根据用户名称查询部门编号
# 根据部门编号查询部门
这是代码从启动到运行的完整逻辑,按顺序执行:
- 导入依赖库:引入FastAPI、数据库操作、数据验证等所有需要的工具
- 创建FastAPI应用:初始化项目核心对象,相当于项目的"总入口"
- 配置数据库连接 :填写MySQL地址,创建异步数据库引擎(专门负责和数据库通信)
- 定义数据库基类 :创建公共父类,自动给所有表添加
创建/更新时间字段 - 定义数据表模型 :编写
部门表和用户表的结构(字段、类型、外键关联) - 编写自动建表函数:项目启动时,自动在MySQL中创建对应的表
- 绑定启动事件:项目一运行,就自动执行建表操作
- 创建数据库会话工厂:批量生产"数据库连接对象",供接口使用
- 编写数据库依赖 :自动管理连接的创建、提交、回滚、关闭,不用手动写
- 定义数据验证模型:规范前端传入的数据格式,防止非法数据入库
- 编写用户CRUD接口 :实现用户的查询、新增、删除、修改核心功能
- 编写关联操作接口 :实现
部门+用户联表操作(新增部门同步加用户、联表查询) - 启动服务:所有接口就绪,可通过URL访问操作数据库
二、核心代码逐行解析
下面将分模块讲解,重点标注增删改查,每行代码都加注释+作用说明。
模块1:基础配置(导入+创建应用)
python
# 导入FastAPI核心:应用对象、依赖注入、异常抛出
from fastapi import FastAPI, Depends, HTTPException
# 导入数据验证工具:严格校验前端传入的数据
from pydantic import BaseModel
# 导入HTTP状态码:比如400参数错误、200成功
from starlette import status
# ===================== 1. 创建FastAPI项目入口 =====================
# 创建FastAPI对象,整个项目的核心,所有接口都挂在这个对象上
app = FastAPI()
模块2:数据库核心配置(引擎+模型)
python
# 导入时间工具、数据库字段类型、增删改查语句、异步数据库工具
from datetime import datetime
from sqlalchemy import DateTime, func, String, Float, Select, Insert, Delete, select, ForeignKey
from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker, AsyncSession
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
# ===================== 2. 数据库连接配置 =====================
# 数据库连接地址:格式= 数据库类型+驱动://用户名:密码@主机:端口/库名?编码
DATABASE_URL = "mysql+aiomysql://root:root@localhost:3306/fastapi_review?charset=utf8"
# 创建异步数据库引擎:负责和MySQL建立通信,相当于"数据库桥梁"
# echo=True:控制台打印执行的SQL语句(方便调试)
# pool_size:连接池大小,控制并发连接数
engine = create_async_engine(DATABASE_URL, echo=True, pool_size=10, max_overflow=20)
# ===================== 3. 数据库模型基类 =====================
# 所有数据表的父类,统一添加公共字段(创建时间、更新时间)
class Base(DeclarativeBase):
# 创建时间:插入数据时自动赋值为当前时间
create_time: Mapped[datetime] = mapped_column(DateTime, default=datetime.now)
# 更新时间:修改数据时自动更新为当前时间
update_time: Mapped[datetime] = mapped_column(DateTime, default=datetime.now, onupdate=func.now())
# ===================== 4. 定义部门表模型 =====================
class Department(Base):
__tablename__ = "t_department" # 数据库表名
# 部门ID:主键、自增
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True, name="department_id", comment="部门ID")
# 部门名称:字符串类型,不能为空
name: Mapped[str] = mapped_column(String(20), nullable=False, name="department_name", comment="部门名称")
# 部门位置:字符串类型,不能为空
location: Mapped[str] = mapped_column(String(100), nullable=False, name="department_location", comment="部门位置")
# ===================== 5. 定义用户表模型 =====================
class User(Base):
__tablename__ = "t_user" # 数据库表名
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True, name="user_id", comment="用户ID")
name: Mapped[str] = mapped_column(String(20), nullable=False, name="user_name", comment="用户名称")
password: Mapped[str] = mapped_column(String(20), nullable=False, name="user_password", comment="用户密码")
salary: Mapped[float] = mapped_column(Float(6, 2), nullable=False, name="user_salary", comment="用户薪水")
birthday: Mapped[datetime] = mapped_column(DateTime, nullable=False, name="user_birthday", comment="出生日期")
# 外键:关联部门表的主键,建立用户和部门的关联关系
department_id: Mapped[int] = mapped_column(ForeignKey("t_department.department_id"), nullable=False, comment="部门ID")
模块3:自动建表 + 数据库依赖(核心工具)
python
# ===================== 6. 异步建表函数 =====================
async def create_tables():
# 打开数据库连接
async with engine.begin() as conn:
# 自动根据模型创建所有数据表(如果表不存在则创建,存在则不操作)
await conn.run_sync(Base.metadata.create_all)
# 项目启动事件:服务一运行,自动执行建表函数
@app.on_event("startup")
async def init():
await create_tables()
# ===================== 7. 数据库会话工厂 =====================
# 生产异步数据库连接(会话),所有接口都用这个连接操作数据库
AsyncSessionLocal = async_sessionmaker(bind=engine, class_=AsyncSession, expire_on_commit=False)
# ===================== 8. 数据库依赖项(自动管理连接) =====================
async def get_session():
# 创建数据库连接
async with AsyncSessionLocal() as session:
try:
yield session # 把连接交给接口使用
await session.commit() # 操作成功,自动提交事务
except Exception as e:
await session.rollback() # 操作失败,自动回滚(数据不丢失)
finally:
await session.close() # 操作完成,自动关闭连接
三、重点:增删改查接口逐行解析
模块4:数据验证模型(规范前端数据)
python
# 新增用户的数据格式:前端必须传这4个参数,类型严格匹配
class UserRequest(BaseModel):
name: str # 用户名
password: str # 密码
salary: float # 薪资
birthday: datetime # 生日
# 修改用户的数据格式:必须传用户ID
class UserUpdate(BaseModel):
id: int
name: str
password: str
salary: float
birthday: datetime
核心1:查询操作(全解析)
python
# ===================== 查询1:查询所有用户 =====================
@app.get("/users") # 接口地址:GET请求
async def get_user_list(session: AsyncSession = Depends(get_session)):
# 1. 生成SQL语句:select * from t_user
stmt = Select(User)
# 2. 执行SQL语句(异步执行,必须加await)
result = await session.execute(stmt)
# 3. 获取结果:转换为用户对象列表
user_list = result.scalars().all()
# 4. 返回数据给前端
return user_list
# ===================== 查询2:根据用户名精确查询 =====================
@app.get("/users/")
async def get_user_by_name(name: str, session: AsyncSession = Depends(get_session)):
# 生成SQL:select * from t_user where user_name = ?
stmt = Select(User).where(User.name == name)
result = await session.execute(stmt)
return result.scalars().all()
# ===================== 查询3:模糊查询 =====================
@app.get("/users/like/")
async def get_user_like_name(name: str, session: AsyncSession = Depends(get_session)):
# 生成SQL:select * from t_user where user_name like '%xxx%'
stmt = Select(User).where(User.name.like(f"%{name}%"))
result = await session.execute(stmt)
return result.scalars().all()
# ===================== 查询4:ID范围查询 =====================
@app.get("/users/in/")
async def get_user_in_ids(ids: str, session: AsyncSession = Depends(get_session)):
# 把字符串"2,4"转换为列表[2,4]
id_list = [int(item) for item in ids.split(",")]
# 生成SQL:select * from t_user where user_id in (2,4)
stmt = Select(User).where(User.id.in_(id_list))
result = await session.execute(stmt)
return result.scalars().all()
# ===================== 查询5:薪资范围查询 =====================
@app.get("/users/between/{min_salary}/{max_salary}")
async def get_user_between_salary(min_salary: float, max_salary: float, session: AsyncSession = Depends(get_session)):
# 生成SQL:select * from t_user where salary between 最小值 and 最大值
stmt = Select(User).where(User.salary.between(min_salary, max_salary))
result = await session.execute(stmt)
return result.scalars().all()
# ===================== 查询6:根据ID查询单个用户 =====================
@app.get("/users/{id}")
async def get_user_by_id(id: int, session: AsyncSession = Depends(get_session)):
# 快速根据主键查询:session.get(模型类, 主键值)
user = await session.get(User, id)
return user
# ===================== 查询7:分页查询 =====================
@app.get("/users/page/{page_no}/{page_size}")
async def get_user_by_id(page_no: int, page_size: int, session: AsyncSession = Depends(get_session)):
# offset:跳过的条数;limit:查询的条数(分页核心)
stmt = Select(User).offset((page_no - 1) * page_size).limit(page_size)
result = await session.execute(stmt)
return result.scalars().all()
核心2:新增操作(逐行注释)
python
# ===================== 新增用户 =====================
@app.post("/users") # POST请求:专门用于新增数据
async def add_user(user: UserRequest, session: AsyncSession = Depends(get_session)):
# 1. 把前端传入的验证数据,封装为数据库用户对象
user_object = User(
name=user.name,
password=user.password,
salary=user.salary,
birthday=user.birthday,
department_id=1 # 补充外键(原代码缺失)
)
# 2. 将对象添加到数据库会话(准备插入)
session.add(user_object)
# 3. 返回成功提示(依赖项会自动commit提交)
return {"code": 200, "message": "添加成功"}
核心3:删除操作(逐行注释)
python
# ===================== 删除用户 =====================
@app.delete("/users/{id}") # DELETE请求:专门用于删除数据
async def delete_user(id: int, session: AsyncSession = Depends(get_session)):
# 1. 生成SQL:delete from t_user where user_id = ?
stmt = Delete(User).where(User.id == id)
# 2. 执行删除语句
await session.execute(stmt)
# 3. 返回成功提示
return {"code": 200, "message": "删除成功"}
核心4:修改操作(逐行注释)
python
# ===================== 修改用户 =====================
@app.put("/users/{id}") # PUT请求:专门用于修改数据
async def update_user(id: int, user_request: UserRequest, session: AsyncSession = Depends(get_session)):
# 1. 根据ID查询要修改的用户
stmt = Select(User).where(User.id == id)
result = await session.execute(stmt)
user = result.scalar_one_or_none()
# 2. 用新数据覆盖旧数据
user.name = user_request.name
user.password = user_request.password
user.salary = user_request.salary
user.birthday = user_request.birthday
# 3. 返回成功提示
return {"code": 200, "message": "修改成功"}
核心5:联表操作(部门+用户)
python
# ===================== 新增部门+同步新增用户 =====================
@app.post("/departments/")
async def add_department(department_add_request: DepartmentAddRequest, session: AsyncSession = Depends(get_session)):
# 1. 创建部门对象
depart = Department(name=department_add_request.name, location=department_add_request.location)
session.add(depart)
await session.commit() # 提交后才能获取部门自增ID
session.refresh(depart) # 同步部门ID到对象
# 2. 遍历用户列表,绑定部门ID,批量新增用户
for user in department_add_request.users:
new_user = User(
name=user.name, password=user.password, salary=user.salary,
birthday=user.birthday, department_id=depart.id
)
session.add(new_user)
return {"code": 200, "message": "添加成功"}
# ===================== 联表查询:根据部门名查用户+部门 =====================
@app.get("/api/users/{name}")
async def get_users_by_department_name(name: str, session: AsyncSession = Depends(get_session)):
# 联表查询:用户表 + 部门表,通过外键关联
stmt = select(User,Department).join(Department,User.department_id == Department.id).where(Department.name == name)
result = await session.execute(stmt)
user_list = result.all()
# 组装数据返回给前端
res = []
for user, dept in user_list:
res.append({
"id": user.id, "name": user.name, "department_name": dept.name
})
return {"code": 200, "data": res}
四、总结
- 全流程核心:导入依赖 → 配置数据库 → 定义表 → 写依赖 → 写CRUD接口
- 增删改查规则 :
- 查询:
Select+execute+ 获取结果 - 新增:创建对象 +
session.add() - 修改:查询对象 + 覆盖属性
- 删除:
Delete+ 条件 + 执行
- 查询:
- 异步关键 :所有数据库操作必须加
await,否则会报错 - 依赖项作用 :自动帮你提交、回滚、关闭连接,不用手动管理