Python Flask 和数据库系统交互

news2025/3/11 6:11:23

Python Flask 和数据库系统交互

  • Python Flask 和数据库系统交互

Python Flask 和数据库系统交互

全栈网页应用程序需要结构化数据的持久性,因此使用数据库的知识和经验是网页开发的先决条件。Python 和Flask 可以与大多数SQL或无SQL数据库系统集成。Python本身附带了一个名为sqlite3的轻量级SQLite数据库。我们将使用SQLite,因为它不需要设置单独的数据库服务器,并且非常适合小规模应用程序。对于生产环境,我们必须使用其他数据库系统,如MySQL、MariaDB或PostgreSQL。为了访问数据库系统并与之交互,我们将使用Flask扩展之一FlaskSQLAlchemy。Flask-SQLAlchemy扩展基于Python的SQLAlchemy库,使该库可用于我们的网页应用程序。SQLAlchemy库提供了一个对象关系映射器(ORM),这意味着它将我们的数据库表映射到Python对象。ORM库的使用不仅加快了开发周期,而且提供了在不更改代码的情况下切换底层数据库系统的灵活性。因此,我们建议使用 SQLAlchemy 或类似的库来处理数据库系统。

要从我们的应用程序与任何数据库系统交互,我们需要像往常一样创建Flask应用程序实例。下一步是使用数据库位置的URL(在SQLite3的情况下是一个文件)配置应用程序实例。创建应用程序实例后,我们将通过将其传递给应用程序实例来创建 SQLAlchemy 实例。使用 SQLite 等数据库时,我们只需在第一次初始化数据库。它可以从Python程序启动,但我们不赞成这种方法,以避免每次启动应用程序时都重置数据库。建议使用 SQLAlchemy 实例从命令行初始化数据库一次。在代码示例之后,我们将讨论初始化数据库的确切步骤。

为了说明SQLAlchemy库在我们的网页应用程序中的使用,我们将创建一个简单的应用程序来添加、列出和删除数据库表中的学生对象。以下是应用程序的示例代码,用于初始化Flask应用程序和数据库实例(SQLAlchemy实例),以及创建 Student 类的 Model 对象:

# 与数据库交互第一部分:创建和删除列表对象
from flask import Flask, render_template, request, redirect
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///student.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)

class Student(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(80), nullable=False)
    grade = db.Column(db.String(20), nullable=True)
    
    def __repr__(self):
        return '<Student %r>' % self.name
    

一旦我们创建了 SQLAlchemy 实例 db,我们就可以使用数据库对象。SQLAlchemy 等ORM库的美妙之处在于,我们可以在 Python 中将数据库模式定义为 Python 类,在 ORM 术语中称为模型。对于我们的代码示例,我们创建了一个类 Student,它继承自基类 db.Model。在这个模型类中,我们定义了 idnamegrade 属性,这些属性将对应于 SQLite3 数据库实例中数据库表 Student 中的三列。对于每个属性,我们定义了它的数据类型,包括最大长度、是否有主键以及是否可以为空。这些额外的属性定义对于以优化的方式配置数据库表非常重要。

在下面的代码片段中,我们将演示一个Python函数 list_students,用于从数据库中获取学生对象列表。此函数映射到示例网页应用程序的 /list URL,它通过在查询实例上使用 all 方法(db 实例的一个属性)从数据库表返回所有 Student对象。请注意,查询实例及其方法可以从基类 db.Model 中获得:

# 第二部分
@app.get('/list')
def list_students():
    students_list = Student.query.all()
    return render_template('app.html', students=students_list)

在下一个代码片段中,我们将编写一个函数(add_student)将学生添加到数据库表中。此函数映射到 /add URL,并期望使用 GET 方法将学生的姓名和成绩作为请求参数传递。要向数据库中添加新对象,我们将使用必要的属性值创建 Student 类的新实例,然后使用 db.Session 实例通过使用 add 函数添加到 ORM 层。add 函数本身不会将实例添加到数据库中。我们将使用 commit 方法将其推送到数据库表中。一旦一个新的学生被添加到我们的数据库表中,我们就会将控制重定向到/list URL。我们使用重定向到此 URL 的原因是,我们想在添加新学生后返回最新的学生列表,并重用我们已经实现的 list_students 函数。add_student 函数的完整代码如下:

# 第三部分
@app.get('/add')
def add_student():
    fname = request.args['fname'
    lname = request.args.get('lname', '')
    grade = request.args.get('grade', '')
    student = Student(name=f"{fname} {lname}", grade=grade)
    db.session.add(student)
    db.session.commit()
    return redirect('/list')

在这个代码示例的最后一部分,我们将编写一个 Python 函数(delete_student)从数据库表中删除一个学生。此函数映射到/delete<int:id> URL。请注意,我们希望客户端发送学生 id(我们使用 /list 列表请求将其与学生列表一起发送)。要删除学生,首先,我们使用学生 ID 查询确切的学生实例。这是通过在查询实例上使用 filter_by 方法来实现的。一旦我们有了确切的 Student 实例,我们就使用 db.Sessiondelete方法,然后提交更改。与 add_student 函数一样,我们将客户端重定向到 /list URL,以向我们的Jinja 模板返回最新的学生列表:

# 第四部分
@app.get('/delete/<int:id>')
def delete_student(id):
    todelete = Student.query.filter_by(id).first()
    db.session.delete(todelete)
    db.session.commit()
    return redirect('/list')

为了在浏览器中显示学生列表,我们创建了一个简单的 Jinja 模板(app.html)。app.html 模板文件将以表格形式提供学生列表。值得注意的是,我们使用 Jinja for 循环动态构建 HTML 表行,如下面的 Jinja 模板所示:

<!DOCTYPE html>
<body>
  <h2>Students</h2>
  {% if students|length > 0 %}
  <table>
    <thead>
      <tr>
        <th scope="col">SNo</th>
        <th scope="col">name</th>
        <th scope="col">grade</th>
      </tr>
    </thead>
    <tbody>
      {% for student in students %}
      <tr>
        <th scope="row">{{student.id}}</th>
        <td>{{student.name}}</td>
        <td>{{student.grade}}</td>
      </tr>
      {% endfor %}
    </tbody>
  </table>
  {% endif %}
</body>
</html>

在启动此应用程序之前,我们应该一次性初始化数据库模式。这可以通过使用 Python 程序来实现,但我们必须确保代码只执行一次,或者只在数据库尚未初始化时执行。推荐的方法是使用 Python shell 手动执行此步骤。在 Python shell 中,我们可以从应用程序模块导入 db 实例,然后使用 db.create_all 方法根据程序中定义的模型类初始化数据库。以下是我们的应用程序用于数据库初始化的示例命令:

>>> from app5 import db
>>> db.create_all()

这些命令将在程序所在的同一目录中创建一个 student.db 文件。要重置数据库,我们可以删除 student.db 文件并重新运行初始化命令,也可以使用 Python shell 中的 db.drop_all 方法。

我们可以使用 curl 实用程序或通过浏览器使用以下 URL 测试应用程序:

http://localhost:5000/list
http://localhost:5000/add?fname=John&Lee=asif&grade=9
http://localhost:5000/delete/<id>

<完>

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

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

相关文章

Qt:事件

目录 处理事件 鼠标事件 键盘事件 定时器事件 窗口事件 虽然 Qt 是跨平台的 C 开发框架&#xff0c;Qt 的很多能力其实是操作系统提供的 只不过 Qt 封装了系统的 API 事件 前面学习过信号槽&#xff1a; 用户进行的各种操作&#xff0c;就可能会产生出信号&#xff0c;可以…

3个 Vue Scoped 的核心原理

大家好&#xff0c;我是大澈&#xff01;一个喜欢结交朋友、喜欢编程技术和科技前沿的老程序员&#x1f468;&#x1f3fb;‍&#x1f4bb;&#xff0c;关注我&#xff0c;科技未来或许我能帮到你&#xff01; 先用一句话概括 Vue Scoped 的核心原理&#xff1a;Vue 的 scoped…

物联网IoT系列之MQTT协议基础知识

文章目录 物联网IoT系列之MQTT协议基础知识物联网IoT是什么&#xff1f;什么是MQTT&#xff1f;为什么说MQTT是适用于物联网的协议&#xff1f;MQTT工作原理核心组件核心机制 MQTT工作流程1. 建立连接2. 发布和订阅3. 消息确认4. 断开连接 MQTT工作流程图MQTT在物联网中的应用 …

ubuntu 20.04 C++ 源码编译 cuda版本 opencv4.5.0

前提条件是安装好了cuda和cudnn 点击下载&#xff1a; opencv_contrib4.5.0 opencv 4.5.0 解压重命名后 进入opencv目录&#xff0c;创建build目录 “CUDA_ARCH_BIN ?” 这里要根据显卡查询一下,我的cuda是11&#xff0c;显卡1650&#xff0c;所以是7.5 查询方法1&#xff1…

2025-03-07 学习记录--C/C++-PTA 习题8-5 使用函数实现字符串部分复制

合抱之木&#xff0c;生于毫末&#xff1b;九层之台&#xff0c;起于累土&#xff1b;千里之行&#xff0c;始于足下。&#x1f4aa;&#x1f3fb; 一、题目描述 ⭐️ 二、代码&#xff08;C语言&#xff09;⭐️ #include <stdio.h> #define MAXN 20void strmcpy( char…

江科大51单片机笔记【10】蜂鸣器(上)

一、蜂鸣器 1.原理 蜂鸣器是一种将电信号转换为声音信号的器件&#xff0c;常同来产生设备的按键音、报警音等提示信号蜂鸣器按驱动方式可分为有源蜂鸣器和无源蜂鸣器&#xff08;外观基本一样&#xff09;有源蜂鸣器&#xff1a;内部自带振荡源&#xff0c;将正负极接上直流…

最新版本WebContext构造函数-避坑

import org.thymeleaf.context.IWebContext; import org.thymeleaf.context.WebContext; 当你想把页面信息全部获取出来存到redis缓存中使用时&#xff0c;SpringWebContext在Spring5中报错 SpringWebContext ctx new SpringWebContext(request, response,request.getServlet…

忘记dedecms后台超级管理员账号和密码的解决方案

解决方案&#xff1a; 方案一、数据库修改&#xff1a; 1、前提是您能登录到数据库后台&#xff0c;登录MySQL数据库管理工具&#xff08;如phpMyAdmin&#xff09; 2、打开数据库中的 dede_admin 表&#xff0c;找到管理员记录&#xff0c;将 pwd 字段的值改成 f297a57a5a7…

Kubernetes中的 iptables 规则介绍

#作者&#xff1a;邓伟 文章目录 一、Kubernetes 网络模型概述二、iptables 基础知识三、Kubernetes 中的 iptables 应用四、查看和调试 iptables 规则五、总结 在 Kubernetes 集群中&#xff0c;iptables 是一个核心组件&#xff0c; 用于实现服务发现和网络策略。iptables 通…

Windows 11下Git Bash执行cURL脚本400问题、CMD/PowerShell不能执行多行文本等问题记录及解决方案

问题 在Postman里可成功执行的POST请求&#xff1a; 找到Postman的Code 因为cURL基本上算是行业标准&#xff0c;所以Postman默认选中cURL&#xff0c;支持切换不同的开发语言&#xff1a; 点击上图右上角的复制按钮&#xff0c;得到cURL脚本。 Windows 11家庭版&#xff…

利用LLMs准确预测旋转机械(如轴承)的剩余使用寿命(RUL)

研究背景 研究问题:如何准确预测旋转机械(如轴承)的剩余使用寿命(RUL),这对于设备可靠性和减少工业系统中的意外故障至关重要。研究难点:该问题的研究难点包括:训练和测试阶段数据分布不一致、长期RUL预测的泛化能力有限。相关工作:现有工作主要包括基于模型的方法、数…

记录小白使用 Cursor 开发第一个微信小程序(二):创建项目、编译、预览、发布(250308)

文章目录 记录小白使用 Cursor 开发第一个微信小程序&#xff08;二&#xff09;&#xff1a;创建项目、编译、预览、发布&#xff08;250308&#xff09;一、创建项目1.1 生成提示词1.2 生成代码 二、编译预览2.1 导入项目2.2 编译预览 三、发布3.1 在微信开发者工具进行上传3…

游戏引擎学习第146天

音高变化使得对齐读取变得不可能&#xff0c;我们可以支持循环声音了。 我们今天的目标是完成之前一段时间所做的音频代码。这个项目并不依赖任何引擎或库&#xff0c;而是一个教育项目&#xff0c;目的是展示从头到尾运行一个游戏所需要的全部代码。无论你对什么方面感兴趣&a…

Java 大视界 -- Java 大数据在智能体育赛事运动员表现分析与训练优化中的应用(122)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…

线性代数之矩阵特征值与特征向量的数值求解方法

文章目录 前言1. 幂迭代法&#xff08;Power Iteration&#xff09;幂法与反幂法求解矩阵特征值幂法求最大特征值编程实现补充说明 2. 逆幂迭代法&#xff08;Inverse Iteration&#xff09;移位反幂法 3. QR 算法&#xff08;QR Algorithm&#xff09;——稠密矩阵理论推导编程…

SparkAi系统体验

DeepSeek-R1-671B大模型满血版私有化部署高可用教程-SparkAi系统集成图文教程 一、SparkAI是什么二、功能模块介绍系统快速体验 三、系统功能模块3.1 AI全模型支持/插件系统3.2 AI智能体应用3.3 AI专业绘画3.4 AI视频生成3.5 Dall-E2/E3/E4绘画3.6 智能思维导图生成3.7 AI绘画广…

视频录像机视频通道是指什么

视频录像机的视频通道是指摄像机在监控矩阵或硬盘录像机设备上的视频输入的物理位置。 与摄像头数量关系&#xff1a;在视频监控系统中&#xff0c;有多少个摄像头就需要多少路视频通道&#xff0c;通道数量决定了视频录像机可接入摄像头的数量&#xff0c;一般硬盘录像机有4路…

【Unity】 HTFramework框架(六十一)Project窗口文件夹锁定器

更新日期&#xff1a;2025年3月7日。 Github源码&#xff1a;[点我获取源码] Gitee源码&#xff1a;[点我获取源码] 索引 Project窗口文件夹锁定器框架文件夹锁定自定义文件夹锁定限制条件 Project窗口文件夹锁定器 在Project窗口中&#xff0c;文件夹锁定器能够为任何文件夹加…

INFINI Labs 产品更新 | Easysearch 增加异步搜索等新特性

INFINI Labs 产品更新发布&#xff01;此次更新&#xff0c;Easysearch 增加了新的功能和数据类型&#xff0c;包括 wildcard 数据类型、Point in time 搜索 API、异步搜索 API、数值和日期字段的 doc-values 搜索支持&#xff0c;Console 新增了日志查询功能。 INFINI Easyse…

3.6c语言

#define _CRT_SECURE_NO_WARNINGS #include <math.h> #include <stdio.h> int main() {int sum 0,i,j;for (j 1; j < 1000; j){sum 0;for (i 1; i < j; i){if (j % i 0){sum i;} }if (sum j){printf("%d是完数\n", j);}}return 0; }#de…