Python web框架fastapi数据库操作ORM(一)

文章目录

  • Fastapi ORM操作
    • 1、创建模型
    • 2、创建数据库连接配置文件
    • 3、启动项目
    • 4、根据模型类创建数据库表
      • 1. 初始化配置,只需要使用一次
      • 2. 初始化数据库,一般情况下只用一次
      • 3. 更新模型并进行迁移
      • 4. 重新执行迁移,写入数据库
      • 5. 回到上一个版本
      • 6. 查看历史迁移记录
    • 5、选课系统接口开发
      • (1)all查询,查询出来的是个list类型数据
      • (2)过滤查询,查询指定内容filter,得到的依然是list类型数据
      • (3)get方法,直接查询
      • (4)模糊查询,查询学号大于2001的学生
      • (5)values查询
      • (6)将数据库数据显示到web页面

Fastapi ORM操作

在大型的web开发中,我们肯定会用到数据库操作,那么FastAPI也支持数据库的开发,你可以用 PostgreSQL、MySQL、 SQLite Oracle 等。本文用SQLite为例。我们看下在fastapi是如何操作设计数据库的。
ORM是“对象-关系-映射”的简称。(Object Relational Mapping,简称ORM)
fastapi是一个很优秀的框架,但是缺少一个合适的orm,官方代码里面使用的是sqlalchemy,Tortoise ORM 是受 Django 启发的易于使用的异步 ORM (对象关系映射器)。
在这里插入图片描述

Tortoise ORM 目前支持以下[数据库]

  • PostgreSQL >= 9.4(使用asyncpg)
  • SQLite(使用aiosqlite)
  • MySQL/MariaDB

安装tortoise
pip install tortoise

安装数据模型迁移工具
pip install aerich

我用的mysql,因此还需要安装aiomysql包:
pip install aiomysql

aerich的功能类似于django的migrate。

1、创建模型

以选课系统为例:
创建个模型类文件 models.py

#导入tortoisefrom tortoise.models import Model
from tortoise import fields#创建班级类
class Clas(Model):name = fields.CharField(max_length=255, description='班级名称')#创建老师类
class Teacher(Model):id = fields.IntField(pk=True)name = fields.CharField(max_length=255, description='姓名')tno = fields.IntField(description='账号')pwd = fields.CharField(max_length=255, description='密码')#课程表
class Course(Model):id = fields.IntField(pk=True)name = fields.CharField(max_length=255, description='课程名')teacher = fields.ForeignKeyField('models.Teacher', related_name='courses', description='课程讲师')#创建学生类
class Student(Model):id = fields.IntField(pk=True)sno = fields.IntField(description='学号')#description 在接口文档有个显示pwd = fields.CharField(max_length=255, description='密码')name = fields.CharField(max_length=255, description='姓名')# 一对多,反向查询时使用related_nameclas = fields.ForeignKeyField('models.Clas', related_name='students')# 多对多courses = fields.ManyToManyField('models.Course', related_name='students',description='学生选课表')

在这里插入图片描述

2、创建数据库连接配置文件

创建settings.py 配置文件

TORTOISE_ORM = {'connections': {'default': {# 'engine': 'tortoise.backends.asyncpg',  PostgreSQL'engine': 'tortoise.backends.mysql',  # MySQL or Mariadb'credentials': {'host': '10.10.0.52','port': '3306','user': 'root','password': 'Jingxxxxxxxx','database': 'fastapi','minsize': 1,'maxsize': 5,'charset': 'utf8mb4',"echo": True}},},'apps': {'models': {#这个models就是自己配置的models.py位置'models': ['models'],'default_connection': 'default',}},'use_tz': False,'timezone': 'Asia/Shanghai'
}

3、启动项目

main.py 启动项目

from fastapi import FastAPI  # FastAPI 是一个为你的 API 提供了所有功能的 Python 类。
import uvicorn
from tortoise.contrib.fastapi import register_tortoisefrom settings import TORTOISE_ORM#创建应用程序,app是应用程序名
app = FastAPI()  # 这个实例将是创建你所有 API 的主要交互对象。这个 app 同样在如下命令中被 uvicorn 所引用# 该方法会在fastapi启动时触发,内部通过传递进去的app对象,监听服务启动和终止事件
# 当检测到启动事件时,会初始化Tortoise对象,如果generate_schemas为True则还会进行数据库迁移
# 当检测到终止事件时,会关闭连接
register_tortoise(app,#数据库配置信息config=TORTOISE_ORM,# generate_schemas=True,  # 如果数据库为空,则自动生成对应表单,生产环境不要开# add_exception_handlers=True,  # 生产环境不要开,会泄露调试信息
)if __name__ == '__main__':#注意,run的第一个参数 必须是文件名:应用程序名uvicorn.run("quickstart:app", port=8080,  reload=True, workers=1)

在这里插入图片描述

启动没报错表示正常连接到了数据库
在这里插入图片描述

4、根据模型类创建数据库表

aerich是一种ORM迁移工具,需要结合tortoise异步orm框架使用。安装aerich

1. 初始化配置,只需要使用一次

初始化之前,需要在settings.py中将aerich自带的models也配置上
在这里插入图片描述

在中高端执行命令

aerich init -t settings.TORTOISE_ORM # TORTOISE_ORM配置的位置)
在这里插入图片描述

初始化完会在当前目录生成一个文件:pyproject.toml和一个文件夹:migrations

  • pyproject.toml:保存配置文件路径,低版本可能是aerich.ini
  • migrations:存放迁移文件

2. 初始化数据库,一般情况下只用一次

将我们在models.py里面配置的表创建到数据库中
aerich init-db
在这里插入图片描述

  1. 此时数据库中就有相应的表格
  2. 如果TORTOISE_ORM配置文件中的models改了名,则执行这条命令时需要增加--app参数,来指定你修改的名字

查看数据库,数据库中就有了我们在模型类里面配置的表
在这里插入图片描述

看下migrations里面的py文件,就是创建表语句
在这里插入图片描述

3. 更新模型并进行迁移

我们在创建模型类之后,通常也会修改
修改model类,重新生成迁移文件,比如添加一个字段
我们给course类添加个地址字段
在这里插入图片描述

aerich migrate [–name] (标记修改操作) # aerich migrate --name add_column --name是给这次迁移起个名字

不加–name,有个默认的名字
迁移文件名的格式为 {version_num}{datetime}{name|update}.py。
在这里插入图片描述
在这里插入图片描述

注意,此时sql并没有执行,数据库中course表中没有xxx字段
在这里插入图片描述

4. 重新执行迁移,写入数据库

aerich upgrade
在这里插入图片描述

此时,就把模型类中新添加爱的字段更新到数据库中了
在这里插入图片描述

5. 回到上一个版本

aerich downgrade
在这里插入图片描述

再看下数据库,新加的字段又没了,回退了
在这里插入图片描述

6. 查看历史迁移记录

aerich history
在这里插入图片描述

5、选课系统接口开发

先看看各个表数据
班级表
在这里插入图片描述

教师表
在这里插入图片描述

课程表
在这里插入图片描述

学生表
在这里插入图片描述

学生课程表
在这里插入图片描述

我们在项目下建个包api,在这个包里面写接口
api/student.py

from fastapi.exceptions import HTTPException#导入models
from models import *from pydantic import BaseModel
from typing import List, Union
from fastapi import APIRouterapi_student = APIRouter()#查看所有学生,注意,tortoise处理数据库要用异步,路径函数前面加async
@api_student.get("/")
async def getAllStudent():#注意,与数据库的操作要加await,得到的是列表类型数据,[Student(),Student(),Student()....]students = await Student.all()print('students',students,type(students))return students#查看某个学生,基于路径参数
@api_student.get("/{student_id}")
async def getOneStudent(student_id:int):#注意,与数据库的操作要加awaitstudent = await Student.all().values("name", "clas__name")return student

在main.py导入api,并做路由分发

from fastapi import FastAPI  # FastAPI 是一个为你的 API 提供了所有功能的 Python 类。
import uvicorn
from tortoise.contrib.fastapi import register_tortoisefrom settings import TORTOISE_ORM#导入api
from api.student import api_student#创建应用程序,app是应用程序名
app = FastAPI()  # 这个实例将是创建你所有 API 的主要交互对象。这个 app 同样在如下命令中被 uvicorn 所引用#路由分发
app.include_router(api_student, prefix="/student", tags=["学生信息接口", ])# 该方法会在fastapi启动时触发,内部通过传递进去的app对象,监听服务启动和终止事件
# 当检测到启动事件时,会初始化Tortoise对象,如果generate_schemas为True则还会进行数据库迁移
# 当检测到终止事件时,会关闭连接
register_tortoise(app,#数据库配置信息config=TORTOISE_ORM,# generate_schemas=True,  # 如果数据库为空,则自动生成对应表单,生产环境不要开# add_exception_handlers=True,  # 生产环境不要开,会泄露调试信息
)if __name__ == '__main__':#注意,run的第一个参数 必须是文件名:应用程序名uvicorn.run("main:app", port=8080,  reload=True, workers=1)

运行程序
在这里插入图片描述

执行查询所有学生
在这里插入图片描述

(1)all查询,查询出来的是个list类型数据

在这里插入图片描述

循环遍历
#循环打印
for stu in students:
print(stu.name, stu.sno)
在这里插入图片描述

(2)过滤查询,查询指定内容filter,得到的依然是list类型数据

student = await Student.filter(name='liuxin')
print(student,type(student))
#得到具体数据
print(student[0].name)

在这里插入图片描述

(3)get方法,直接查询

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

此时得到的就是模型类对象,可以直接获取属性值
在这里插入图片描述

(4)模糊查询,查询学号大于2001的学生

students = await Student.filter(sno__gt=2001)
print(students)

得到的也是列表
在这里插入图片描述

#查询学号是2001和2002的学生,在某个范围内,用__in
students = await Student.filter(sno__in=[2001,2002])

在这里插入图片描述

(5)values查询

只查出指定字段数据,得到的是列表套字典数据,有几个字典,取决于查询出几条记录
students = await Student.filter(sno__range=[1, 10000]).values(‘name’,‘sno’)
for stu in students:
print(stu)

在这里插入图片描述

(6)将数据库数据显示到web页面

在student.py 这个api文件里面
返回页面模板

#导入模板的包
from fastapi.templating import Jinja2Templates# 实例化Jinja2对象,并将文件夹路径设置为以templates命名的文件夹
templates = Jinja2Templates(directory="templates")接口:
@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上下文对象,是个字典)

创建templates文件夹下的index.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>学生信息</title>
</head>
<body><p>学生信息页面</p><ul>{% for stu in students %}<li>姓名: {{stu.name}} 学号: {{stu.sno}}</li>{% endfor%}
</ul></body>
</html>

在这里插入图片描述

启动程序,访问
在这里插入图片描述

浏览器访问
在这里插入图片描述

当然,也可以借助bootstrap让页面更好看

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>学生信息</title><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet"integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
</head>
<body><div class="col-md-8 offset-md-2"><h2>学生信息</h2><table class="table table-hover table-striped"><thead><tr><td>姓名</td><td>学号</td><td>班级</td></tr></thead><tbody>{% for student in students%}<tr><td>{{student.name}}</td><td>{{student.sno}}</td><td>{{student.clas_id}}</td></tr>{%endfor%}</tbody>
</table>
</div></body>
</html>

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/710912.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Oracle 11g升级19c 后部分查询功能很慢

*Oracle 11g升级19c 后部分查询功能很慢 今天生产突然有个查询非常慢&#xff0c;日志显示执行了50秒左右&#xff0c;但是从日志中拿出SQL在PLSQL执行&#xff0c;发现用时不到1秒&#xff0c;查看SQL,怀疑是下面几种原因导致 1、使用函数不当 UNIT.UNIT_CODE LIKE CONCAT(‘…

状态码转文字!!!(表格数字转文字)

1、应用场景&#xff1a;在我们的数据库表中经常会有status这个字段&#xff0c;这个字段经常表示此类商品的状态&#xff0c;例如&#xff1a;0->删除&#xff0c;1->上架&#xff0c;0->下架&#xff0c;等等。 2、我们返回给前端数据时&#xff0c;如果在页面显示0…

【Unity】在Unity中导出WebGL并读取Excel数据的实现方法

在游戏开发中&#xff0c;数据的处理和导出是至关重要的环节之一。Unity作为一款强大的游戏开发引擎&#xff0c;提供了丰富的工具和功能来处理和导出数据&#xff0c;包括将游戏导出为WebGL应用&#xff0c;并读取外部数据文件&#xff0c;比如Excel表格。本文将介绍如何在Uni…

gpt生成器,批量gpt文章生成器

GPT&#xff08;生成式预训练模型&#xff09;生成器软件在当今的数字化时代扮演着越来越重要的角色&#xff0c;它们通过人工智能技术&#xff0c;可以自动生成各种类型的文章内容&#xff0c;为用户提供了无限的创作可能性。本文将介绍6款不同的GPT生成器软件&#xff0c;并介…

STM32自学☞AD单通道

程序的最终运行成果: 当转动电位器时&#xff0c;数值和电压值发生变化 ad.c文件 #include "stm32f10x.h" #include "stm32f10x_adc.h" #include "ad.h" #include "stdint.h" void ad_Init(void) { /* 初始化步骤&#xff1a;…

java学习笔记-初级

一、变量 1.双标签 <!-- 外部js script 双标签 --><script srcmy.js></script> 在新文件my.js里面写&#xff1a; 2.字符串定义&#xff1a; //外单内双var str 我是一个"高富帅"的程序员;console.log(str);// 字符串转义字符 都是用 \ 开头 …

MySQL-MHA搭建、故障测试

一、架构说明 MHA&#xff08;Master High Availability&#xff09;是一个用于 MySQL 主从复制管理和自动故障转移的开源工具集。MHA 的主要目的是提供 MySQL 环境的高可用性和自动故障转移功能&#xff0c;确保在主库发生故障时能够快速切换到备库&#xff0c;降低业务中断时…

ElasticSearch之Completion Suggester

写在前面 通过completion suggester可以实现如下的效果&#xff1a; 其实就是做的like xxx%这种。通过FST这种数据结构来存储&#xff0c;实现快速的前缀匹配&#xff0c;并且可以将es所有的数据加载到内存中所以速度completion的查询速度非常快。 需要注意&#xff0c;如果…

HUAT——Fasc——算法组学习笔记

目录 系列文章目录 前言 一、配置相关环境 二、创建工作空间 1.创建工作空间并初始化 2.进入 src 创建 ros 包并添加依赖 三、HelloWorld(C版) 1.进入 ros 包的 src 目录编辑源文件 2.编辑 ros 包下的 Cmakelist.txt文件 3.进入工作空间目录并编译 四 运行程序 五 …

docker 基础(二)

常见命令 Docker最常见的命令就是操作镜像、容器的命令&#xff0c;详见官方文档&#xff1a;https://docs.docker.com/ 数据卷 命令说明文档地址docker volume create创建数据卷docker volume createdocker volume ls创建数据卷docker volume lsdocker volume rm查看所有数…

Swiper实现轮播效果

swiper官网&#xff1a;https://3.swiper.com.cn/ <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title&…

中间件-Nginx加固(控制超时时间限制客户端下载速度并发连接数)

中间件-Nginx加固&#xff08;控制超时时间&限制客户端下载速度&并发连接数&#xff09; 1.1 Nginx 控制超时时间配置1.2 Nginx 限制客户端下载速度&并发连接数 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 1.1 Nginx 控制超…

机器学习图像识别如何处理标签以外的图像?

机器学习图像识别技术是一种基于人工智能的图像处理方法&#xff0c;它通过训练大量的图像数据集来让计算机学习如何识别和分类图像。在图像识别任务中&#xff0c;我们通常需要对图像进行标注和分类&#xff0c;以便让计算机能够从中学习。但是&#xff0c;有时候我们可能会遇…

大数据旅游数据分析:基于Python旅游数据采集可视化分析推荐系统

文章目录 基于Python旅游数据采集可视化分析推荐系统一、项目概述二、项目说明三、开发环境四、功能实现五、系统页面实现用户登录注册系统首页数据操作管理价格与销量分析旅游城市和景点等级分析旅游数据评分情况分析旅游数据评论情况分析旅游景点推荐Django系统后台管理 六、…

【前端早早聊直播回顾】Harmony 时代的跨端方案

上周末&#xff0c;凡泰极客CTO - 徐鹏受邀出席「前端早早聊」直播活动&#xff0c;并以【跨端新挑战-鸿蒙时代的跨端】为主题进行演讲。 摘取部分分享实录&#xff1a; 终端系统的数量和种类不断增长&#xff0c;开发者面临着多平台开发的挑战。以往开发者一般只需要维护iOS、…

2024年3月阿里云服务器大规模价格下调后优惠折扣表

阿里云服务器ECS等核心产品价格全线下调&#xff0c;最高幅度达55%&#xff0c;2024年3月1日生效&#xff0c;针对ECS部分在售产品的官网折扣价、ECS计算型节省计划进行调整&#xff0c;生效后&#xff0c;基于官网折扣价的新购和续费&#xff0c;将按照新的价格进行计费。阿里…

程序媛的mac修炼手册-- Node.js入门篇

最近因为参与一个微信小程序的开发&#xff0c;开始摸索JavaScript。期间&#xff0c;需要基于Node.js安装微信开发工具的依赖项&#xff0c;所以又顺带学习了Node.js的包管理工具npm&#xff08;Node Package Manager&#xff09;。不过&#xff0c;之前看到国外的全栈大佬​​…

flutter学习(一) 安装以及配置环境

首先需要下载flutter&#xff0c;然后解压 然后配置环境变量&#xff0c;配置到bin目录就行 配置完之后cmd运行flutter doctor 你就会发现&#xff0c;都是错 此时脑海里响起&#xff0c;卧槽&#xff0c;怎么回事&#xff0c;咋办 别着急&#xff0c;我教你。。。 问题 这…

内网穿透 nas/树莓派+ipv4服务器 (ipv6)

nas 1.有个服务器 2.有个nas https://github.com/snail007/goproxy/blob/master/README_ZH.md https://github.com/snail007/proxy_admin_free/blob/master/README_ZH.md 2个官网一个是程序&#xff0c;一个是网站 手册 https://snail007.host900.com/goproxy/manual/zh/#/?i…

rocketmq+rocket-dashboard win10安装部署+注册为Windows服务

1.1 首先去官网下载zip包 选择自己需要的版本 下载 | RocketMQ 1.2 、下载后&#xff0c;解压到指定目录 1.3、配置RocketMQ环境变量 注意&#xff0c;看对应的版本需要jdk版本 1.4、启动mqnameserver 进入bin目录下&#xff0c;双击启动mqnamesrv.cmd 启动后&#xff0c;…