【实战Flask API项目指南】之六 数据库集成 SQLAlchemy

实战Flask API项目指南之 数据库集成

本系列文章将带你深入探索实战Flask API项目指南,通过跟随小菜的学习之旅,你将逐步掌握 Flask 在实际项目中的应用。让我们一起踏上这个精彩的学习之旅吧!

前言

在上一篇文章中,我们实现了一个 图书馆里系统API的后端,小菜觉得美中不足的是它使用一个 Python的列表用于存储图书的信息,是一个 本地版图书管理系统后端API。重新启动程序图书的数据就会丢失了。所以这节,我们将用上数据库来帮助小菜解决这一痛点,实现持久化数据存储。

当小菜踏入Flask后端开发的世界时,数据库是存储和管理数据的关键。

Flask并没有内置数据库功能,但是提供了扩展机制,可以方便地集成第三方数据库库。本文将介绍如何在 Flask 项目中集成SQLAlchemy,这是一个流行的Python ORM库。 我们将会在上一节课的基础上改写,让读者朋友们了解如何在 Flask应用中集成数据库。

注意:本文直接直接上代码,干货满满。




SQLAlchemy

1. 安装依赖

Flask 中,可以使用各种数据库,如SQLite、MySQL、PostgreSQL等。首先,需要安装所需的数据库驱动库,例如flask-sqlalchemy用于集成 SQLAlchemy

在使用 SQLAlchemy 进行数据库操作时,大部分操作是相似的,无论使用哪种数据库类型。(本文使用的是 MYSQL)

首先我们需要安装对应的依赖库,使用以下命令。

pip install flask-sqlalchemy flask-mysqldb

2. 配置数据库

Flask 应用中配置数据库连接信息。在应用的配置中,添加数据库的连接字符串。

  • 确保将usernamepasswordlocalhostflask替换为自己的MySQL数据库的用户名、密码、主机和数据库名称。
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
# mysql示例
# app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://username:password@localhost/database'
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:123456@localhost/flask'


db = SQLAlchemy(app)

3. 定义数据模型

使用SQLAlchemy,可以定义数据模型作为 Python 类。每个类对应一个表,类的属性对应表中的列。数据模型是数据库中表格的抽象表示,它定义了表格的结构和字段。

在下面代码中,定义了一个名为Book的数据模型,它有三列

  • book_id 字段作为主键,用作主键(primary key),唯一的,不允许为空

  • title 字段表示书籍的标题,字符串类型,最大长度为100字符,不允许为空

  • author 字段表示书籍的作者,字符串类型,最大长度为50字符,不允许为空

  • 因为在我们的案例中,数据表只需要这三列。

class Book(db.Model):
    book_id = db.Column(db.Integer, primary_key=True, unique=True, nullable=False)
    title = db.Column(db.String(100), nullable=False)
    author = db.Column(db.String(50), nullable=False)

附上SQLAlchemy中常用的列设置选项:

选项描述
primary_key=True将列标记为主键,用于唯一标识每行数据。
nullable=False指定列不允许为空值。
unique=True确保列中的值是唯一的,不允许重复值。
default=<value>为列设置默认值,如果插入数据时未提供值,则使用默认值。
index=True创建列的索引,以提高检索性能。
autoincrement=True自动生成递增的值(通常与主键一起使用)。
onupdate=<value>在更新行时设置列的值为指定的值。
server_default=<value>设置列的服务器默认值,通常在数据库层面实现。

4. 常用数据库操作

当使用SQLAlchemy时,有许多常用的数据库操作方法,用于执行CRUD(创建、读取、更新、删除)操作。以下是一些常用的SQLAlchemy操作方法示例:

请注意,这些示例假定你已经正确配置了SQLAlchemy和数据库连接。

  1. 创建数据(Create)

    # 创建一个新对象并将其添加到数据库中
    new_book = Book(title="Sample Book", author="John Doe")
    db.session.add(new_book)
    db.session.commit()
    
  2. 读取数据(Read)

    # 查询所有书籍
    books = Book.query.all()
    
    # 根据条件查询书籍
    specific_book = Book.query.filter_by(title="Sample Book").first()
    
  3. 更新数据(Update)

    # 查询要更新的对象
    book_to_update = Book.query.filter_by(title="Sample Book").first()
    
    # 更新对象的属性
    book_to_update.author = "New Author"
    db.session.commit()
    
  4. 删除数据(Delete)

    # 查询要删除的对象
    book_to_delete = Book.query.filter_by(title="Sample Book").first()
    
    # 从数据库中删除对象
    db.session.delete(book_to_delete)
    db.session.commit()
    
  5. 过滤和排序(Filter and Sort)

    # 查询所有作者是"John Doe"的书籍
    johns_books = Book.query.filter_by(author="John Doe").all()
    
    # 查询前5本书籍并按书名升序排列
    top_books = Book.query.order_by(Book.title).limit(5).all()
    
  6. 聚合和统计(Aggregate and Count)

    # 计算书籍总数
    book_count = Book.query.count()
    
    # 计算不同作者的书籍数量
    author_book_count = db.session.query(Book.author, db.func.count(Book.book_id)).group_by(Book.author).all()
    



SQLAlchemy中常用的操作及其描述:

操作描述
定义数据模型使用db.Model定义数据模型,并定义字段及其属性。
创建数据表使用db.create_all()创建定义的数据模型对应的数据表。
查询数据使用db.session.query()创建查询对象,并添加查询条件。
插入数据使用db.session.add()添加新数据对象,并提交更改。
更新数据获取数据对象,修改属性后使用db.session.commit()提交更改。
删除数据使用db.session.delete()添加要删除的数据对象,并提交更改。
过滤条件在查询中使用filterfilter_by等方法添加过滤条件。
排序使用order_by方法指定查询结果的排序方式。
限制数量使用limitoffset限制查询结果的数量和偏移量。
聚合和统计使用func函数进行聚合和统计操作,如func.count()
关联表查询使用relationship定义关联关系,使用join进行关联查询。
事务管理使用db.session.begin()开始事务,使用commit提交更改,或rollback回滚更改。
批量操作使用db.session.bulk_insert_mappings()进行批量插入,使用db.session.bulk_update_mappings()进行批量更新。
连接查询使用join进行多表连接查询,使用select_fromouterjoin等方法进行不同类型的连接。
原始SQL查询使用db.session.execute()执行原始的SQL查询。

5. 创建数据表

app.py的末尾,添加以下代码来创建数据表:

Flask-SQLAlchemy中,可以使用db.create_all()来创建所有定义的数据模型对应的数据表。在app.py的末尾,添加以下代码:

db.create_all()

但有时候会抛出一个 RuntimeError 的异常,

提示说在应用程序上下文之外工作,所以在前面添加 with app.app_context(),如下所示:

# 创建数据表
with app.app_context():
    db.create_all()  # 或其他需要应用上下文的操作

6. 持久化数据存储的图书管理系统

这里将会在上一节课 本地版图书管理系统 的基础上,使用SQLAlchemy 改写成持久化数据存储的图书管理系统。

上代码

# -*- coding: utf-8 -*-

from flask_sqlalchemy import SQLAlchemy
from flask import (Flask, jsonify, request)

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:123456@localhost/flask'  # 替换为你的数据库 URI
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)


# 定义Book模型类
class Book(db.Model):
    book_id = db.Column(db.Integer, primary_key=True, unique=True, nullable=False)
    title = db.Column(db.String(100), nullable=False)
    author = db.Column(db.String(50), nullable=False)


# 获取所有书籍
@app.route("/books", methods=["GET"])
def get_all_books():
    books = Book.query.all()
    book_list = [{"id": book.book_id, "title": book.title, "author": book.author} for book in books]
    return jsonify(book_list), 200


# 获取特定书籍
@app.route("/books/<int:book_id>", methods=["GET"])
def get_book(book_id):
    book = Book.query.get(book_id)
    if book:
        return jsonify({"id": book.book_id, "title": book.title, "author": book.author}), 200
    return jsonify({"error": "Book not found."}), 404


# 创建新书籍
@app.route("/books", methods=["POST"])
def create_book():
    data = request.json
    new_book = Book(title=data["title"], author=data["author"])
    db.session.add(new_book)
    db.session.commit()
    return jsonify({"id": new_book.book_id, "title": new_book.title, "author": new_book.author}), 201


# 更新书籍信息
@app.route("/books/<int:book_id>", methods=["PUT"])
def update_book(book_id):
    book = Book.query.get(book_id)
    if book:
        data = request.json
        book.title = data["title"]
        book.author = data["author"]
        db.session.commit()
        return jsonify({"id": book.book_id, "title": book.title, "author": book.author}), 200
    return jsonify({"error": "Book not found."}), 404


# 删除书籍
@app.route("/books/<int:book_id>", methods=["DELETE"])
def delete_book(book_id):
    book = Book.query.get(book_id)
    if book:
        db.session.delete(book)
        db.session.commit()
        return "", 204
    return jsonify({"error": "Book not found."}), 404


if __name__ == "__main__":
    app.run(debug=True)

现在,小菜可以使用GET、POST、PUT和DELETE请求来访问API端点,并对图书数据进行操作。这个例子演示了如何在 Flask 应用中集成数据库、定义数据模型、执行数据库操作以及使用API端点来操作数据。这将帮助小菜更好地理解 Flask 中的数据库集成。

总结

这篇文章深入探讨了在Flask应用中集成数据库的关键步骤,通过引入SQLAlchemy这一流行的Python ORM库,实现了数据的持久化存储。文章首先介绍了安装依赖以及配置数据库的过程,然细讲解了如何定义数据模型以及常见的数据库操作方法。重点强调了如何使用Flask-SQLAlchemy扩展来简化数据库交互的过程。

通过以上步骤,小菜已经成功地在 Flask 应用中集成了MySQL数据库,并实现了图书的增删改查等操作。小菜获得了以下知识:

  • 如何配置Flask应用以连接数据库。
  • 如何使用SQLAlchemy定义数据模型和表格结构。
  • 如何执行常见的数据库操作,包括创建、读取、更新和删除数据。
  • 如何使用Flask-SQLAlchemy扩展简化数据库交互。

通过本文的学习,小菜已经理解了Flask中数据库集成和操作,这为后面小菜需要实现后端API平台打下了扎实的基础!

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

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

相关文章

出海营销必看:如何避免邮件被识别为垃圾邮件

对于现在的商业环境来说&#xff0c;邮件通信已经成为企业与客户、合作伙伴以及员工之间沟通和交流的重要方式。然而&#xff0c;尽管企业发送的邮件通常都是正常的、合规的&#xff0c;有时候却会被系统错误地标记为营销邮件。这个情况给企业带来了很多困扰。 如果企业的邮件…

FMC子卡解决方案:FMC214-基于FMC兼容1.8V IO的Full Camera Link 输出子卡

FMC214-基于FMC兼容1.8V IO的Full Camera Link 输出子卡 一、板卡概述   基于FMC兼容1.8V IO的Full Camera Link 输出子卡支持Base、Middle、Full Camera link信号输出&#xff0c;兼容1.8V、2.5V、3.3V IO FPGA信号输出。适配xilinx不同型号开发板和公司内部各FMC载板。北…

Langchain-Chatchat项目:4.1-P-Tuning v2实现过程

常见参数高效微调方法(Parameter-Efficient Fine-Tuning&#xff0c;PEFT)有哪些呢&#xff1f;主要是Prompt系列和LoRA系列。本文主要介绍P-Tuning v2微调方法。如下所示&#xff1a; Prompt系列比如&#xff0c;Prefix Tuning(2021.01-Stanford)、Prompt Tuning(2021.09-Goo…

图片去水印不伤原图快来试试这些方法

也许很多朋友都曾经历过和我相似的困扰。费尽心思找到心仪的图片&#xff0c;却发现下载的图片大多都带有水印。尝试了各种方法想要消除图片上的水印&#xff0c;但效果不尽如人意&#xff0c;反而让画面变得更加凌乱模糊&#xff0c;那么&#xff0c;有什么方法可以图片去水印…

点击跳到详情页

父页面 <template><view class"order-list"><cu-custom bgColor"bg-gradual-blue" :isBack"true"><block slot"content">荒料管理</block></cu-custom><view class"" ><!-- 订…

物流小程序制作教程:从零到有,详细解析

随着互联网的快速发展&#xff0c;物流行业也逐渐实现了数字化转型。为了满足消费者对更加便捷、高效的服务需求&#xff0c;许多物流企业选择制作自己的小程序。本文将通过乔拓云网后台&#xff0c;带你轻松搭建物流小程序&#xff0c;主要分为以下几个部分&#xff1a; 一、进…

Github 自动化部署到GitHub Pages

1.准备工作 新建仓库 新建项目 配置 vite.config.ts base: ./,部署应用包时的基本URL&#xff0c;例&#xff1a;vue-cli 5.x 配置 publicPath 推送到远程仓库 2.配置 GitHub Token 点击 Settings -> Actions -> General 找到 Workflow permissions&#xff0c;选中第…

名称空间,作用域,global和nonlocal

一、名称空间 加载顺序&#xff1a; 1、内置命名空间 2、全局命名空间 3、局部命名空间 取值顺序&#xff1a; 1、局部命名空间 2、全局命名空间 3、内置命名空间 二、作用域 三、global python之闭包https://blog.csdn.net/Python_1981/article/details/133636994 四…

串口通信(8)串口中断“边接收边解析数据“的通信程序

本文为博主 日月同辉&#xff0c;与我共生&#xff0c;csdn原创首发。希望看完后能对你有所帮助&#xff0c;不足之处请指正&#xff01;一起交流学习&#xff0c;共同进步&#xff01; > 发布人&#xff1a;日月同辉,与我共生_单片机-CSDN博客 > 欢迎你为独创博主日月同…

JavaScript 基础

文章目录 JavaScript初识JavaScriptJavaScript 的组成第一个程序 语法变量的使用动态类型基本数据类型number 数字类型string 字符串类型转义字符求长度字符串拼接 boolean 布尔类型undefined 未定义数据类型null 空值类型 运算符数组数组的遍历函数 对象使用 字面量 创建对象 …

openGauss学习笔记-112 openGauss 数据库管理-管理用户及权限-行级访问控制

文章目录 openGauss学习笔记-112 openGauss 数据库管理-管理用户及权限-行级访问控制 openGauss学习笔记-112 openGauss 数据库管理-管理用户及权限-行级访问控制 行级访问控制特性将数据库访问控制精确到数据表行级别&#xff0c;使数据库达到行级访问控制的能力。不同用户执…

ZYNQ实验---IQ调制实现SSB PART2

一、前言 本文实验在ZYNQ实验—IQ调制实现SSB PART1的基础上进行优化完善。 下图为IQ调制实现SSB PART1中设想实现设计框图 该图设计存在的几个问题&#xff1a; PC-PS的UDP传输存在丢包中断控制发包实际不适合流数据的传输采用的BRAM模块可以存储的空间较小&#xff0c;PC…

正则表达式续篇

位置锚定&#xff1a; ^:行首锚定&#xff0c;表示以什么为开头 例如&#xff1a; $:行尾锚定&#xff0c;表示以什么为结尾 例如&#xff1a; ^&#xff1a;匹配的是空行 例如&#xff1a; ^root$&#xff1a;匹配整行&#xff0c;而且整行只能有这一个字符串 实验&#x…

“第五十八天”

这里c语言的强制类型转换&#xff0c;大小端的问题在之前C语言中都提过了。 这里之前提过的边界对齐在补一点东西。 现代计算机通常是按字节编址&#xff0c;即每个字节对应一个地址&#xff1b;通常也支持按字、按半字、按字节寻址&#xff1b; 之前提过&#xff0c;字和字节…

基于单片机设计的电子柜锁

一、前言 随着现代社会的不断发展&#xff0c;电子柜锁的应用越来越广泛。传统的机械柜锁存在一些不便之处&#xff0c;例如钥匙容易丢失、密码容易泄露等问题。设计一款基于单片机的电子柜锁系统成为了一个有趣而有意义的项目。 该电子柜锁系统通过电磁锁作为柜锁的开关&…

ViT Vision Transformer超详细解析,网络构建,可视化,数据预处理,全流程实例教程

关于ViT的分析和教程&#xff0c;网上又虚又空的东西比较多&#xff0c;本文通过一个实例&#xff0c;将ViT全解析。 包括三部分内容&#xff0c;网络构建&#xff1b;orchview.draw_graph 将网络每一层的结构与输入输出可视化&#xff1b;数据预处理。附完整代码 网络构建 …

通过USM(U盘魔术大师)在PE环境下使用分区助手拷贝磁盘——无损升级硬盘

这里写自定义目录标题 背景本次使用技术步骤1、添加新硬盘2、添加PE3、开机进入BIOS&#xff0c;进入PE4、开始拷贝磁盘5、调整分区5.1 删除系统盘前的所有分区5.2 修改硬盘分区表格式为GUID5.3 新建引导分区 6、修复引导7、大功告成 背景 由于硬盘空间不够的时候就需要更换硬盘…

桥接模式birdge

简介 桥接模式&#xff1a;将抽象与实现相分离&#xff0c;使他们可以独立变化。 角色 抽象化&#xff08;Abstraction&#xff09;角色&#xff1a; 该类持有一个对实现角色的引用&#xff0c;抽象角色中的方法需要实现角色来实现&#xff0c;抽象角色一般为抽象类&#xf…

0基础学习PyFlink——个数滚动窗口(Tumbling Count Windows)

大纲 Tumbling Count WindowsmapreduceWindow Size为2Window Size为3Window Size为4Window Size为5Window Size为6 完整代码参考资料 之前的案例中&#xff0c;我们的Source都是确定内容的数据。而Flink是可以处理流式&#xff08;Streaming&#xff09;数据的&#xff0c;就是…

每日自动化提交git

目前这个功能&#xff0c;有个前提&#xff1a; 这个git代码仓库&#xff0c;是一个人负责&#xff0c;所以不存在冲突问题 我这个仓库地址下载后的本地路径是&#xff1a;D:\Projects\Tasks 然后我在另外一个地方新建了一个bat文件&#xff1a; bat文件所在目录为&#xff1a…