【实战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 SQLAlchemyapp = 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}), 200return jsonify({"error": "Book not found."}), 404# 创建新书籍
@app.route("/books", methods=["POST"])
def create_book():data = request.jsonnew_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.jsonbook.title = data["title"]book.author = data["author"]db.session.commit()return jsonify({"id": book.book_id, "title": book.title, "author": book.author}), 200return 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 "", 204return jsonify({"error": "Book not found."}), 404if __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平台打下了扎实的基础!

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

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

相关文章

day53【子序列】1143.最长公共子序列 1035.不相交的线 53.最大子序和

文章目录 1143. 最长公共子序列1035.不相交的线53. 最大子序和 1143. 最长公共子序列 题目链接&#xff1a;力扣链接 讲解链接&#xff1a;代码随想录讲解 题意&#xff1a;给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长 公共子序列 的长度。如果不存在 …

微信自动回复有什么好处?怎么设置?

微信自动回复有什么好处&#xff1f; 首先&#xff0c;它可以帮助我们节省时间和精力。当我们无法立即回复消息时&#xff0c;自动回复可以及时告知对方我们的状况&#xff0c;避免对方的焦虑和不便。 其次&#xff0c;自动回复可以增强沟通效率。无论是工作还是个人生活中&a…

gtsam初探以及结合LIO-SAM算法的一些理解

概述 GTSAM&#xff08;Georgia Tech Smoothing and Mapping&#xff09;是基于因子图的C库&#xff0c;本篇基于GTSAM对因子图优化做一个简单了解和梳理&#xff0c;并以LIO-SAM为例进一步分析因子图优化在SLAM中的应用。 参考链接&#xff1a; [0]gtsam官方文档 [1]https:/…

mongo常用操作符及查询例子

比较操作符&#xff1a; $eq&#xff1a;匹配字段值等于指定值。 $ne&#xff1a;匹配字段值不等于指定值。 $gt&#xff1a;匹配字段值大于指定值。 $gte&#xff1a;匹配字段值大于或等于指定值。 $lt&#xff1a;匹配字段值小于指定值。 $lte&#xff1a;匹配字段值小于或等…

最小化安装移动云大云操作系统--BCLinux-R8-U2-Server-x86_64-231017版

有个业务系统因为兼容性问题&#xff0c;需要安装el8.2的系统&#xff0c;因此对应安装国产环境下的BCLinuxR8U2系统来满足用户需求。BCLinux-R8-U2-Server是中国移动基于AnolisOS8.2深度定制的企业级X86服务器通用版操作系统。本文记录在DELL PowerEdge R720xd服务器上最小化安…

Redis-分布式锁

Redis-setnx实现分布式锁 Redis实现分布式锁主要利用Redis的setnx命令。setnx是SET if not exists(如果不存在&#xff0c;则SET)的简写。(NX是互斥、EX是设置超时时间) 但是如上会面临一个问题&#xff0c;当业务执行时间太长&#xff0c;导致业务还没执行完锁已到期&#xf…

Flask三种文件下载方法

Flask 是一个流行的 Python Web 框架&#xff0c;它提供了多种方法来实现文件下载。在本文中&#xff0c;我们将介绍三种不同的方法&#xff0c;以便你能够选择最适合你应用程序的方法。 方法一&#xff1a;使用 send_file 函数 send_file 函数是 Flask 中最常用的文件下载方法…

令人深刻的c#工具和库

为了方便大家开发&#xff0c;介绍一些库和框架。 框架 CAP - 具有本地持久消息功能的EventBus&#xff0c;用于SOA或微服务架构中的系统集成。Cinchoo ETL - .NET的ETL框架&#xff08;用于CSV&#xff0c;Flat&#xff0c;Xml&#xff0c;JSON&#xff0c;键值格式文件的分…

CentOS开机自动运行jar程序实现

前面已经有一篇文章介绍jar包如何在CentOS上运行&#xff0c;《在linux上运行jar程序操作记录》 后来发现系统重启后不能自动运行&#xff0c;导致每次都要手动打开&#xff0c;这篇介绍如何自动开机启动运行jar程序。 一、找到JDK程序执行位置 [rootlocalhost /]# which jav…

2.Vue3项目(二):vue项目创建,项目必需的基础依赖配置,项目集成各种第三方依赖

目录 一、环境配置 1.下载node.js 2.pnpm的配置 二、创建项目 1.先创建好项目文件夹

【开题报告】基于 Spring Boot 的在线预约导游系统的设计与实现

1.引言 在旅游行业中&#xff0c;导游起到了重要的作用&#xff0c;他们为游客提供了专业的旅游服务和相关信息。然而&#xff0c;传统的导游预约方式可能存在一些问题&#xff0c;如信息不透明、预约流程繁琐等。因此&#xff0c;我们计划开发一个基于 Spring Boot 的在线预约…

学习笔记二十九:K8S配置管理中心Configmap实现微服务配置管理

Configmap概述 Configmap概述Configmap能解决哪些问题&#xff1f;Configmap应用场景局限性 Configmap创建方法命令行直接创建通过文件创建指定目录创建configmap 编写configmap资源清单YAML文件使用Configmap通过环境变量引入&#xff1a;使用configMapKeyRef通过环境变量引入…

Azure机器学习 - 在 Azure 机器学习中上传、访问和浏览数据

目录 一、环境准备二、设置内核三、下载使用的数据四、创建工作区的句柄五、将数据上传到云存储空间六、访问笔记本中的数据七、创建新版本的数据资产八、清理资源 机器学习项目的开始阶段通常涉及到探索性数据分析 (EDA)、数据预处理&#xff08;清理、特征工程&#xff09;以…

Flutter 使用 dio 遇到的问题合集

泪流满面啊&#xff0c;&#xff0c;&#xff0c;&#xff0c;&#xff0c; 1. postHttpLogin-异常-----DioException [bad response]: The request returned an invalid status code of 500. /// 错误代码如下&#xff1a;Future<String?> postHttpLogin(String textC…

Java 项目 服务器 日志配置

最近 在搞一个0-1的项目 就想把 服务器日志配置 记录一下 我们使用的是 单体微服务项目 首先你需要一个xml <?xml version"1.0" encoding"UTF-8"?> <configuration><!--定义日志存放的位置--><springProperty scope"context&…

Java语法 - 01

Java基础 Java 是一种广泛使用的高级编程语言&#xff0c;最初由Sun Microsystems于1995年发布。它被设计为具有简单、可移植和面向对象的特性&#xff0c;以满足跨平台应用程序开发的需求。以下是一些关于 Java 的简介&#xff1a; 跨平台性&#xff1a;Java 程序可以在不同…

基于QT的简易计算器(一)

目录 0 简介1.设计原理1.1界面设计1.1.1界面基本布局1.1.2 界面调整和美化1.1.2 控件重命名 1.2 连接信号和槽1.3 软件逻辑1.3.1四则运算1.3.2 连续运算&#xff08;不完全&#xff09;的原理1.3.3 清屏1.3.4 退格1.3.5 等于1.3.6 小数点 2.总结与拓展 0 简介 最近在学QT&…

Django实战项目-学习任务系统-自定义URL拦截器

接着上期代码框架&#xff0c;6个主要功能基本实现&#xff0c;剩下的就是细节点的完善优化了。 首先增加URL拦截器&#xff0c;你不会希望没有登录用户就可以进入用户主页各种功能的&#xff0c;所以增加URL拦截器可以解决这个问题。 Django框架本身也有URL拦截器&#xff0…

el-dialog点击esc退出时如何清除数据,如何触发方法

例如下面的el-dialog <el-dialog :title"title" :visible.sync"open" width"1400px" append-to-body close"handleDialogClose">...</el-dialog>当:visible.sync的时候才能键盘esc控制关闭窗口 当close的时候,键盘esc关闭…

12504 - Updating a Dictionary (UVA)

题目链接如下&#xff1a; Online Judge 我的代码如下&#xff1a; #include <string> #include <iostream> #include <map> #include <set> // #define debugint T, loc1, loc2; std::string s, key, value; char ch[] "-*";int main()…