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

#导入tortoise

from 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_name
    clas = 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_tortoise

from 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 APIRouter

api_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):
    #注意,与数据库的操作要加await
    student = 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_tortoise

from 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>

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

uniapp+vue基于Android的图书馆借阅系统qb4y3-nodejs-php-pyton

uni-app框架&#xff1a;使用Vue.js开发跨平台应用的前端框架&#xff0c;编写一套代码&#xff0c;可编译到Android、小程序等平台。 框架支持:springboot/django/php/Ssm/flask/express均支持 前端开发:vue 语言&#xff1a;pythonjavanode.jsphp均支持 运行软件:idea/eclip…

【Javascript编程实操01】判断最大数、奇偶数、是否成年

目录 前言 1、求两个数的最大数 代码&#xff1a; 实现效果&#xff1a; 2、判断一个整数是偶数还是奇数 代码&#xff1a; 实现效果&#xff1a; 3、判断一个人的年龄是否满18岁 代码&#xff1a; 实现效果&#xff1a; 总结 前言 从今天开始正式进入了Web前端第二…

GitLab--Merge Request 权限管理

场景 团队在日常开发工作中需要进行分支管理&#xff0c;通常使用feature分支进行开发&#xff0c;然后依次合并到dev分支、release分支&#xff0c;整个代码合并过程不仅仅是代码合并还需要对代码进行审核&#xff0c;如果在线下进行审核合并&#xff0c;这样操作无法保留痕迹…

反射详解-获取构造方法-动态代理

反射是Java语言中的一个关键特性&#xff0c;它允许程序在运行时访问类、接口、字段和方法的信息&#xff0c;并且可以动态地调用方法或改变字段值。 以下是关于Java反射的一些主要方面&#xff1a; 类加载器&#xff08;Class Loader&#xff09;&#xff1a; Java反射开始于…

内网穿透 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…

Tiktok矩阵系统搭建的逻辑和源代码!

很多和我一样从事外贸工具开发的朋友都清楚&#xff0c;TikTok矩阵系统不仅确保了平台的高效运行&#xff0c;还为用户提供了个性化的内容推荐&#xff0c;从而大大提升了用户黏性&#xff0c;因此很多人都乐意去开发类似的工具&#xff0c;下面我们就来说说Tiktok矩阵系统搭建…

Vue3 在SCSS中使用v-bind

template 先创建一个通用的页面结构 <template><div class"v-bubble-bg"></div> </template>js 在JS中先对需要用的数据进行定义&#xff1a; 可以是参数&#xff0c;也可以是data <script setup>const props defineProps({bgCol…

[万字长文] 从 Vue 3 的项目模板学习 tsconfig 配置

文章目录 一、tsconfig.json 的作用二、基本介绍三、Vue 3 的 tsconfig.json 的结构分析1. 总配置 tsconfig.json2. Web 侧 tsconfig.app.jsona. 继承基础配置b. 包含和排除的文件c. 编译器选项 3. 测试 tsconfig.vitest.jsona. 继承的基础配置b. 包含和排除的文件c. 编译器选项…

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&…

苹果的“汽车梦”宣告失败,转战AI?能hold住吗?

文 | BFT机器人 一觉睡醒&#xff0c;苹果就宣布了一件爆炸性的新闻&#xff0c;那就是坚持多年和受到很多行业大佬支持和期待的“泰坦”宣布结束了&#xff01;将原有负责汽车项目的大部分主力军转战到AI核心上&#xff0c;这消息一出&#xff0c;业内外纷纷对苹果的这个决定…

仓储自动化新解:托盘四向穿梭车驶入智能工厂 智能仓储与产线紧密结合

目前&#xff0c;由于对仓库存储量的要求越来越高&#xff0c;拣选、输送以及出入库频率等要求也越来越高&#xff0c;对此&#xff0c;在物流仓储领域&#xff0c;自动化与智能化控制技术得以快速发展&#xff0c;货架穿梭车在自动库领域的应用越来越广泛。现阶段&#xff0c;…

从 iOS 设备恢复数据的 20 个iOS 数据恢复工具

作为 iPhone、iPad 或 iPod 用户&#xff0c;您可能普遍担心自己可能会丢失存储在珍贵 iOS 设备中的所有宝贵数据。数据丢失的原因多种多样&#xff0c;这里列出了一些常见原因&#xff1a; 1. iOS 软件更新 2. 恢复出厂设置 3. 越狱 4. 误操作删除数据 5. iOS 设备崩溃 …

CMake、OpenCV 和单元测试

我写了很多关于 CMake 的文章&#xff0c;如果你感兴趣&#xff0c;可以点击以下链接阅读&#xff1a; CMake VS MakeCMake&#xff1a;在构建世界掀起风暴现代 CMake 使用技巧CMake 交叉编译CMake 生成器已开启 我们将继续对 CMake 的探索&#xff0c;这篇文章技术性高&…

如何解决 C/C++ 编译器优化导致的编译BUG(程序崩溃)支援VC++/CLANG/GCC

本文仅适用于&#xff0c;有愿意、爱捣鼓的童靴。 因编译器优化导致编译BUG&#xff0c;即DEBUG下面无故障稳定工作&#xff0c;但RELESE下程序会在特定函数位置上崩溃。 这要求 C/C 开发人员拥有最基本的素质&#xff0c;需要能够承受&#xff0c;逐行审视编译器输出的目标平…

获取当前数据 上下移动

点击按钮 上下移动 当前数据 代码 // 出国境管理 登记备案人员列表 <template><a-row><a-col span"24"><a-card :class"style[a-table-wrapper]"><!-- 出国境 登记备案人员列表 --><a-table:rowKey"records >…

【Java】查看class文件的jdk编译版本的两种方式

一、使用文本编辑工具EditPlus 使用EditPlus打开该class文件&#xff0c;字符集选择16进制&#xff08;Hex viewer&#xff09;。 仅看第一行数据&#xff0c;前面8个字节CA FE BA BE是固定的。 之后4个字节00 00 是次版本。 次版本后面的4个字节00 34 就是jdk版本。 jdk版本…

Java代码块

Java代码块 普通代码块 普通代码块在对象创建时执行&#xff0c;创建一个对象就会执行一次&#xff0c;可把构造函数中的冗余代码放到普通代码块中 public class Test {public void method() {// 普通代码块{int x 10;System.out.println(x);}public method(){}} }普通代码块…

使用mininet快速入门ONOS路由交换技术与原理-路由篇

上篇文章 《使用mininet快速入门ONOS路由交换技术与原理-交换篇》 使用mininet搭建了一个简单的网络拓扑&#xff0c;并实现了同一交换机下同网段多主机的通信&#xff0c;其中涉及到的通信知识主要以二层mac地址通信为主。 但在芸芸网络的世界中&#xff0c;主机间的通信除了…

Education Codeforces Round 162(Div.2) A~E

A.Moving Chips (思维) 题意&#xff1a; 给一个长度为 n n n的数组 a a a&#xff0c; a i 1 a_i1 ai​1或者 a i 0 a_i0 ai​0&#xff0c;现在可以选择一个 1 1 1&#xff0c;然后将其与左侧最近的 0 0 0交换。询问使得所有的 1 1 1连在一起&#xff0c;中间没有 0 0 0…

Vue+SpringBoot打造不良邮件过滤系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统用户模块2.2 收件箱模块2.3 发件箱模块2.4 垃圾箱模块2.5 回收站模块2.6 邮箱过滤设置模块 三、实体类设计3.1 系统用户3.2 邮件3.3 其他实体 四、系统展示五、核心代码5.1 查询收件箱档案5.2 查询回收站档案5.3 新…