Python web框架fastapi数据库操作ORM(二)增删改查逻辑实现方法

简介: Python web框架fastapi数据库操作ORM(二)增删改查逻辑实现方法


今天,我们一起探讨一下fastapi的增删改查逻辑实现


ORM数据库增删改查操作

需要导入的包

from pydantic import BaseModel

from typing import Union,List

#保存数据到数据库,对用户输入数据进行校验
class StudentIn(BaseModel):
name: str
pwd: str
sno: int
clas_id: int
courses: List[int] = []

1.添加单条记录

api接口实现

1.添加方式一

@api_student.post("/",tags=["添加学生"])
async def addStudent(stu: StudentIn):
    # 添加数据库操作
    # 方式1
    student = Student(name=stu.name, pwd=stu.pwd, sno=stu.sno, clas_id=stu.clas_id)
    #插入数据库动作
    await student.save()
    print(student, dir(student))
    return student

接口测试

查看数据库,数据已入库

2.添加方式二

# 方式2
student = await Student.create(name=stu.name, pwd=stu.pwd, sno=stu.sno, clas_id=stu.clas_id)
print(student, dir(student))

数据库查看,添加成功

2.多对多表添加记录

由于多对多那张表,没有对应的模型类,所以一般无法通过模型类直接添加删除

需要借助学生表的多对多字段courses来处理

# 添加多对多关系记录
courses = await Course.filter(id__in=stu.courses)
print("courses", courses)
#添加的时候,要用*打散的方式传参
await student.courses.add(*courses)
print("student", student.courses)

查看数据库

可以看到id 13 对15和16,多对多插入成功

1.一对多查询

#一对多查询
student = await Student.get(name="wangfang")

#直接通过外键字段查询,班级名称
clasname = await student.clas.values('name')
print("班级名称",clasname)

#查询所有学生的班级名称,通过外键__字段值
students = await Student.all().values("name","clas__name")
print(students)

2.多对多查询

#多对多查询,根据某个学生查询报的班名称和老师名称
student = await Student.get(name="wangfang")
print(await student.courses.all().values('name','teacher__name'))

#查询所有学生的课程名称和老师名称
students = await Student.all().values("name", "clas__name",'courses__name')
print(students)

查询某一个学生的接口

#查看某个学生,基于路径参数
@api_student.get("/{student_id}")
async def getOneStudent(student_id:int):
    #注意,与数据库的操作要加await
    student = await Student.get(id=student_id)
    print(student.name)


    return student


3.更新学生信息接口

#更新学生信息,使用put请求
@api_student.put("/student/{student_id}")
async def update_student(student_id: int, student: StudentIn):
    #将对象转换为字典
    data = student.dict(exclude_unset=True)
    #将courses字段排除,因为student表中没有courses字段
    courses = data.pop("courses")
    print(data, courses)
    #更新用filter方法。因为filter查出来的对象有update方法
    await Student.filter(id=student_id).update(**data)

    #设置多对多课程
    courses = await Course.filter(id__in=student.courses)
    edit_student = await Student.get(id=student_id)
    #先把原来课程清空,再添加更新后的
    await edit_student.courses.clear()
    await edit_student.courses.add(*courses)

    return student


先看下源数据库13号学生信息

多对多表

在接口执行更新

更新后

多对多表


4.删除学生接口

导入异常包

from fastapi.exceptions import HTTPException

该异常类可以设置响应状态码,描述信息等

@api_student.delete("/student/{student_id}")
async def delete_student(student_id: int):
    #返回删除的数量
    deleted_count = await Student.filter(id=student_id).delete()  # 条件删除
    #输入的id不存在删除报错
    if not deleted_count:
        raise HTTPException(status_code=404, detail=f"Student {student_id} not found")
    #能正产给删除,返回空
    return {}

删除对应学生的时候,也会级联删除对应的多对多表中数据

我们删除13号学生

执行删除请求

查看数据库,13号学生已被删除



查看多对多表13号也被删除

完整代码:

from fastapi import Request

from fastapi.exceptions import HTTPException

#导入模板的包
from fastapi.templating import Jinja2Templates

# 实例化Jinja2对象,并将文件夹路径设置为以templates命名的文件夹
templates = Jinja2Templates(directory="templates")


from pydantic import BaseModel

from typing import Union,List


#导入models
from models import *


from fastapi import APIRouter

api_student = APIRouter()


#保存数据到数据库,对用户输入数据进行校验
class StudentIn(BaseModel):
    name: str
    pwd: str
    sno: int
    clas_id: int
    courses: List[int] = []


#查看所有学生
@api_student.get("/")
async def getAllStudent():
    #注意,与数据库的操作要加await,得到的是queryset类型数据,[Student(),Student(),Student()....]
    # students = await Student.all()
    # print('students',students,type(students))
    #
    # #循环打印
    # for stu in students:
    #     print(stu.name, stu.sno)


    #过滤查询,查询指定内容filter,得到的依然是list类型数据
    # student = await Student.filter(name='liuxin')
    # print(student,type(student))
    # #得到具体数据
    # print(student[0].name)

    #get方法
    # student = await Student.get(name="wangfang")
    # print(student,type(student))
    # print(student.name,student.sno)


    #模糊查询,查询学号大于2001的学生
    # students = await Student.filter(sno__gt=2001)
    #查询学号是2001和2002的学生
    # students = await Student.filter(sno__in=[2001,2002])
    # print(students)


    #values查询,只查出指定字段数据
    # students = await Student.filter(sno__range=[1, 10000]).values('name','sno')
    # print(students)
    # for stu in students:
    #     print(stu)


    #一对多查询
    # student = await Student.get(name="wangfang")

    #
    # #直接通过外键字段查询,班级名称
    # clasname = await student.clas.values('name')
    # print("班级名称",clasname)
    #
    # #查询所有学生的班级名称,通过外键__字段值
    # students = await Student.all().values("name","clas__name")
    # print(students)

    #多对多查询,根据某个学生查询报的班名称和老师名称
    student = await Student.get(name="wangfang")
    print(await student.courses.all().values('name','teacher__name'))

    #查询所有学生的课程名称和老师名称
    students = await Student.all().values("name", "clas__name",'courses__name')
    print(students)



    return students


#将学生信息显示到页面
@api_student.get("/index")
async def show_student(request:Request):
    students = await Student.all()
    return templates.TemplateResponse(
        'index.html', #第一个参数放模板文件
        {
            'request': request,  # 注意,返回模板响应时,必须有request键值对,且值为Request请求对象
            'students':students

        }, #context上下文对象,是个字典
    )




#查看某个学生,基于路径参数
@api_student.get("/{student_id}")
async def getOneStudent(student_id:int):
    #注意,与数据库的操作要加await
    student = await Student.get(id=student_id)
    print(student.name)


    return student



#更新学生信息,使用put请求
@api_student.put("/student/{student_id}")
async def update_student(student_id: int, student: StudentIn):
    #将对象转换为字典
    data = student.dict(exclude_unset=True)
    #将courses字段排除,因为student表中没有courses字段
    courses = data.pop("courses")
    print(data, courses)
    #更新用filter方法。因为filter查出来的对象有update方法
    await Student.filter(id=student_id).update(**data)

    #设置多对多课程
    courses = await Course.filter(id__in=student.courses)
    edit_student = await Student.get(id=student_id)
    #先把原来课程清空,再添加更新后的
    await edit_student.courses.clear()
    await edit_student.courses.add(*courses)

    return student




@api_student.delete("/student/{student_id}")
async def delete_student(student_id: int):
    #返回删除的数量
    deleted_count = await Student.filter(id=student_id).delete()  # 条件删除
    #输入的id不存在删除报错
    if not deleted_count:
        raise HTTPException(status_code=404, detail=f"Student {student_id} not found")
    #能正产给删除,返回空
    return {}






@api_student.post("/",tags=["添加学生"])
async def addStudent(stu: StudentIn):
    # 添加数据库操作
    # 方式1
    # student = Student(name=stu.name, pwd=stu.pwd, sno=stu.sno, clas_id=stu.clas_id)
    # #插入数据库动作
    # await student.save()
    # print(student, dir(student))


    # 方式2
    student = await Student.create(name=stu.name, pwd=stu.pwd, sno=stu.sno, clas_id=stu.clas_id)
    print(student, dir(student))

    # 添加多对多关系记录
    courses = await Course.filter(id__in=stu.courses)
    print("courses", courses)
    #添加的时候,要用*打散的方式传参
    await student.courses.add(*courses)
    print("student", student.courses)

    return courses



相关文章
|
7月前
|
安全 数据安全/隐私保护
Web渗透-逻辑漏洞
逻辑漏洞主要因程序逻辑不严谨或复杂导致处理错误,常见于越权访问、密码修改、支付等环节。漏洞统计显示,越权操作和逻辑漏洞占比最高,尤其账号安全风险突出,如任意重置密码、验证码暴力破解等。漏洞分类中,越权访问分为水平越权(同权限用户间数据访问)和垂直越权(跨权限数据访问)。
323 0
Web渗透-逻辑漏洞
|
11月前
|
SQL 数据库 开发者
Python中使用Flask-SQLAlchemy对数据库的增删改查简明示例
这样我们就对Flask-SQLAlchemy进行了一次简明扼要的旅程,阐述了如何定义模型,如何创建表,以及如何进行基本的数据库操作。希望你在阅读后能对Flask-SQLAlchemy有更深入的理解,这将为你在Python世界中从事数据库相关工作提供极大的便利。
935 77
|
11月前
|
XML 数据库 Android开发
Android数据库的使用(增删改查)
本文介绍了一个简单的数据库操作Demo,包含创建数据库、增删改查功能。通过5个按钮分别实现创建数据库、插入数据、删除数据、更新数据和查询数据的操作。代码结构清晰,适合初学者学习Android SQLite数据库基础操作。
346 5
|
11月前
|
数据库 Android开发 开发者
Android常用的room增删改查语句(外部数据库)
本文分享了将一个原生数据库驱动的单词APP重构为使用Room库的过程及遇到的问题,重点解决了Room中增删改查的常用语句实现。文章通过具体示例(以“forget”表为例),详细展示了如何定义实体类、Dao接口、Database类以及Repository和ViewModel的设计与实现。同时,提供了插入、删除、更新和查询数据的代码示例,包括模糊查询、分页加载等功能。此外,针对外部数据库导入问题,作者建议可通过公众号“计蒙不吃鱼”获取更多支持。此内容适合有一定Room基础的开发者深入学习。
326 0
Android常用的room增删改查语句(外部数据库)
|
12月前
|
移动开发 前端开发 JavaScript
H5 页面与 Web 页面的制作方法
H5页面制作利用HTML5、CSS3和JavaScript技术,结合H5编辑器或框架(如Adobe Dreamweaver、Ionic),注重移动设备兼容性与响应式布局。Web页面制作则基于传统HTML、CSS和JavaScript,借助文本编辑器或IDE完成开发。两者区别在于技术版本、交互性和浏览器支持:H5更互动、现代,但可能不兼容旧浏览器;Web页面更静态、兼容性广。根据需求选择:高交互选H5,广泛兼容选Web。
1693 6
|
数据采集 Web App开发 API
FastAPI与Selenium:打造高效的Web数据抓取服务 —— 采集Pixabay中的图片及相关信息
本文介绍了如何使用FastAPI和Selenium搭建RESTful接口,访问免版权图片网站Pixabay并采集图片及其描述信息。通过配置代理IP、User-Agent和Cookie,提高爬虫的稳定性和防封禁能力。环境依赖包括FastAPI、Uvicorn和Selenium等库。代码示例展示了完整的实现过程,涵盖代理设置、浏览器模拟及数据提取,并提供了详细的中文注释。适用于需要高效、稳定的Web数据抓取服务的开发者。
854 15
FastAPI与Selenium:打造高效的Web数据抓取服务 —— 采集Pixabay中的图片及相关信息
|
存储 JSON JavaScript
WEB CAD插件通过上下文对象MxPluginContext修改UI界面的方法
本文介绍了如何使用MxPluginContext动态控制MxCAD项目的UI界面。通过该上下文对象,开发者可以灵活设置UI配置,如控制操作栏显隐、编辑按钮、添加侧边栏等。具体方法包括调用`getUiConfig()`获取并修改`mxUiConfig.json`中的属性,实现界面的定制化。此外,还提供了控制命令行聚焦的功能,解决输入框焦点锁定问题。详细代码示例和效果对比图展示了具体实现步骤,帮助开发者更好地适配项目需求。
|
SQL 存储 安全
Web 常见攻击方式及防御方法
【10月更文挑战第25天】Web 安全是一个复杂而重要的领域,攻击者不断寻找新的攻击方法,我们需要不断加强防御措施,提高安全意识,以保障 Web 应用的安全运行。通过采取多种防御手段的综合运用,我们可以有效地降低 Web 攻击的风险,保护用户的信息和财产安全。同时,随着技术的不断发展,我们也需要持续关注和研究新的安全威胁和防御方法,以应对不断变化的安全形势。
1729 56
|
JSON 安全 中间件
Python Web 框架 FastAPI
FastAPI 是一个现代的 Python Web 框架,专为快速构建 API 和在线应用而设计。它凭借速度、简单性和开发人员友好的特性迅速走红。FastAPI 支持自动文档生成、类型提示、数据验证、异步操作和依赖注入等功能,极大提升了开发效率并减少了错误。安装简单,使用 pip 安装 FastAPI 和 uvicorn 即可开始开发。其优点包括高性能、自动数据验证和身份验证支持,但也存在学习曲线和社区资源相对较少的缺点。
659 15
|
关系型数据库 MySQL 数据库连接
Unity连接Mysql数据库 增 删 改 查
在 Unity 中连接 MySQL 数据库,需使用 MySQL Connector/NET 作为数据库连接驱动,通过提供服务器地址、端口、用户名和密码等信息建立 TCP/IP 连接。代码示例展示了如何创建连接对象并执行增删改查操作,确保数据交互的实现。测试代码中,通过 `MySqlConnection` 类连接数据库,并使用 `MySqlCommand` 执行 SQL 语句,实现数据的查询、插入、删除和更新功能。