【python】flask结合SQLAlchemy,在视图函数中实现对数据库的增删改查
✨✨ 欢迎大家来到景天科技苑✨✨
🎈🎈 养成好习惯,先赞后看哦~🎈🎈
🏆 作者简介:景天科技苑
🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。
🏆《博客》:Python全栈,前后端开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi,flask等框架,linux,shell脚本等实操经验,网站搭建,面试宝典等分享。所属的专栏:flask框架零基础,进阶应用实战教学
景天的主页:景天科技苑
文章目录
- flask项目中数据库连接设置
- 数据库基本操作
- 模型类定义
- flask中数据表操作
- 创建和删除表
- 数据操作
- 添加一条数据
- 添加多条数据
- 更新操作
- 删除操作
- 关于数据库锁
- 总结
上一章,我们学到了在python中怎么使用SQLAlchemy来操作数据库,在工作中,我们经常结合flask来操作数据库。本章我们来一起深入探讨下!!!
flask项目中数据库连接设置
- 在 Flask-SQLAlchemy 中,数据库的链接配置信息使用URL指定,而且程序使用的数据库必须保存到Flask的 SQLALCHEMY_DATABASE_URI 配置项中
manage.py,代码:
# SQLAlchemy的链接配置:"数据库名://账户名:密码@服务器地址:端口/数据库名称?配置参数选项"
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:123@127.0.0.1:3306/flaskdemo?charset=utf8mb4"# 如果不使用mysqldb改用pymysql,则需要在连接时指定pymysql
# app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:Jin*******7!@10.10.0.52:3306/students?charset=utf8mb4"
其他设置项:
# 动态追踪修改设置,如未设置只会提示警告
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = True
# 查询时会显示原始SQL语句
app.config["SQLALCHEMY_ECHO"] = True
常用的SQLAlchemy字段类型与python数据类型对照
常用的SQLAlchemy列约束选项
数据库基本操作
- 在SQLAlchemy中,添加、修改、删除操作,均由数据库会话(sessionSM)管理。
- 会话用 db.session 表示。在准备把数据写入数据库前,要先将数据添加到会话中然后调用 db.session.commit() 方法提交会话。
- 在SQLAlchemy 中,查询操作是通过 query 对象操作数据。
- 最基本的查询是返回表中所有数据,也可以通过filter或filter_by过滤器进行更精确的数据库查询。
模型类定义
我们后面会把模型创建到单独的文件中,但是现在我们先把模型类写在main.py文件中。
from flask import Flask
from flask_sqlalchemy import SQLAlchemyapp = Flask(__name__)
# 连接数据库连接url
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:Jinghao31357!@10.10.0.52:3306/students?charset=utf8mb4"
# 动态追踪修改设置,如未设置只会提示警告
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = True
# 查询时会显示原始SQL语句
app.config["SQLALCHEMY_ECHO"] = True# 把SQLAlchemy组件注册到项目中
db = SQLAlchemy()
db.init_app(app)#创建模型类
class Student(db.Model):"""学生信息模型"""#下面的字段配置相当于执行sql语句如下"""CREATE TABLE tb_student2 (id INTEGER NOT NULL COMMENT '主键' AUTO_INCREMENT, name VARCHAR(15) COMMENT '姓名', age SMALLINT COMMENT '年龄', sex BOOL COMMENT '性别', email VARCHAR(128) COMMENT '邮箱地址', money NUMERIC(10, 2) COMMENT '钱包', PRIMARY KEY (id), UNIQUE (email))"""# 声明与当前模型绑定的数据表名称__tablename__ = "tb_student2"id = db.Column(db.Integer, primary_key=True, comment="主键")name = db.Column(db.String(15), index=True, comment="姓名")age = db.Column(db.SmallInteger, comment="年龄")sex = db.Column(db.Boolean, default=True, comment="性别")email = db.Column(db.String(128), unique=True, comment="邮箱地址")money = db.Column(db.Numeric(10, 2), default=0.0, comment="钱包")def __repr__(self): # 相当于django的__str__return f"{self.name}<{self.__class__.__name__}>"class Course(db.Model):"""课程模型""""""CREATE TABLE tb_course (id INTEGER NOT NULL COMMENT '主键' AUTO_INCREMENT, name VARCHAR(255) COMMENT '课程', price NUMERIC(8, 2) COMMENT '价格', PRIMARY KEY (id), UNIQUE (name))"""__tablename__ = "tb_course"id = db.Column(db.Integer, primary_key=True, comment="主键")name = db.Column(db.String(255), unique=True, comment="课程")price = db.Column(db.Numeric(8, 2), comment="价格")def __repr__(self): # 相当于django的__str__return f"{self.name}<{self.__class__.__name__}>"class Teacher(db.Model):"""老师模型""""""CREATE TABLE tb_teacher (id INTEGER NOT NULL COMMENT '主键' AUTO_INCREMENT,name VARCHAR(255) COMMENT '姓名',`option` ENUM('讲师','助教','班主任'),PRIMARY KEY (id),UNIQUE (name))"""__tablename__ = "tb_teacher"id = db.Column(db.Integer, primary_key=True, comment="主键")name = db.Column(db.String(255), unique=True, comment="姓名")option = db.Column(db.Enum("讲师", "助教", "班主任"), default="讲师")def __repr__(self):return f"{self.name}<{self.__class__.__name__}>"if __name__ == '__main__':#要想执行创建表,需要调用db.creat_all(),db要想被调用,需要放到app上下文里面with app.app_context():# 如果没有提前声明模型中的数据表,则可以采用以下代码生成数据表,# 如果数据库中已经声明了有数据表,则不会继续生成db.create_all()app.run(debug=True)
flask中数据表操作
创建和删除表
创建表
# 在视图内调用:
@app.route("/create")
def create_table():db.create_all() # 为项目中被识别的所有模型创建数据表return "ok"# 在视图以外的地方调用:
with app.app_context():# create_all()方法执行的时候,需要放在模型的后面# 检测数据库中是否存在和模型匹配的数据表。# 如果没有,则根据模型转换的建表语句进行建表。# 如果找到,则不会进行额外处理db.create_all()
删除表
# 在视图内调用:
@app.route("/drop")
def drop_table():db.drop_all() # 为项目中被识别的所有模型删除数据表return "ok"# 在视图以外的地方调用:with app.app_context():db.drop_all() # 慎用,很给力的!!这表示删除数据库中所有模型对应的表。
数据操作
添加一条数据
#在视图函数中实现增删改查
@app.route("/data")
def data():"""添加数据"""# # 添加一条数据student = Student(name="小明",age=17,sex=True,email="xiaoming@qq.com",money=30.50)db.session.add(student)db.session.commit()return "ok"
get请求访问data路径
可以看到数据已被添加到表中
添加多条数据
student_list = [Student(name="小黑", age=16, sex=True, email="xiaohei@qq.com", money=1000),Student(name="小红", age=15, sex=False, email="xiaohong@qq.com", money=1200),Student(name="小兰", age=11, sex=True, email="xiaolan@qq.com", money=600),Student(name="小白", age=21, sex=False, email="xiaobai@qq.com", money=2900),
]
db.session.add_all(student_list)
db.session.commit()
查看数据库
更新操作
更新一条数据
student = Student.query.get(3)
student.age = 18
db.session.commit()
更新之前,我们先看下3号的年龄
浏览器访问后查看
可见年龄被修改成18
更新多条数据
Student.query.filter(Student.sex == True).update({Student.money: Student.age * 100,
})
db.session.commit()
可见sex为True的money改成了年龄乘以100
删除操作
删除一条数据
student = Student.query.get(5)
db.session.delete(student)
db.session.commit()
id为5的数据被删除
删除多条数据
Student.query.filter(Student.sex==False).delete()
db.session.commit()
删之前先看看数据库表数据
浏览器访问/data
查看数据库,sex为False的全部被删除
完整代码:
from flask import Flask
from flask_sqlalchemy import SQLAlchemyapp = Flask(__name__)
# 连接数据库连接url
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:Jinghao31357!@10.10.0.52:3306/students?charset=utf8mb4"
# 动态追踪修改设置,如未设置只会提示警告
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = True
# 查询时会显示原始SQL语句
app.config["SQLALCHEMY_ECHO"] = True# 把SQLAlchemy组件注册到项目中
db = SQLAlchemy()
db.init_app(app)#创建模型类
class Student(db.Model):"""学生信息模型"""# 声明与当前模型绑定的数据表名称__tablename__ = "tb_student2"id = db.Column(db.Integer, primary_key=True, comment="主键")name = db.Column(db.String(15), index=True, comment="姓名")age = db.Column(db.SmallInteger, comment="年龄")sex = db.Column(db.Boolean, default=True, comment="性别")email = db.Column(db.String(128), unique=True, comment="邮箱地址")money = db.Column(db.Numeric(10, 2), default=0.0, comment="钱包")def __repr__(self): # 相当于django的__str__return f"{self.name}<{self.__class__.__name__}>"class Course(db.Model):"""课程模型"""__tablename__ = "tb_course"id = db.Column(db.Integer, primary_key=True, comment="主键")name = db.Column(db.String(255), unique=True, comment="课程")price = db.Column(db.Numeric(8, 2), comment="价格")def __repr__(self): # 相当于django的__str__return f"{self.name}<{self.__class__.__name__}>"class Teacher(db.Model):"""老师模型"""__tablename__ = "tb_teacher"id = db.Column(db.Integer, primary_key=True, comment="主键")name = db.Column(db.String(255), unique=True, comment="姓名")#枚举类型option = db.Column(db.Enum("讲师", "助教", "班主任"), default="讲师")def __repr__(self):return f"{self.name}<{self.__class__.__name__}>"#在视图函数中实现增删改查
@app.route("/data")
def data():"""添加数据"""# # 添加一条数据# student = Student(# name="小明",# age=17,# sex=True,# email="xiaoming@qq.com",# money=30.50# )# db.session.add(student)# db.session.commit()# # 添加多条数据# student_list = [# Student(name="小黑", age=16, sex=True, email="xiaohei2@qq.com", money=1000),# Student(name="小红", age=15, sex=False, email="xiaohong2@qq.com", money=1200),# Student(name="小兰", age=11, sex=True, email="xiaolan2@qq.com", money=600),# Student(name="小白", age=21, sex=False, email="xiaobai2@qq.com", money=2900),# ]# db.session.add_all(student_list)# db.session.commit()"""更新操作"""# # 更新一条数据# student = Student.query.get(3)# student.age = 18# db.session.commit()# 更新多条数据# Student.query.filter(Student.sex == True).update({# Student.money: Student.age * 100,# })# db.session.commit()"""删除操作"""# # 删除一条数据# student = Student.query.get(5)# db.session.delete(student)# db.session.commit()# # 删除多条数据Student.query.filter(Student.sex==False).delete()db.session.commit()return "ok"if __name__ == '__main__':#要想执行创建表,需要调用db.creat_all(),db要想被调用,需要放到app上下文里面with app.app_context():# 如果没有提前声明模型中的数据表,则可以采用以下代码生成数据表,# 如果数据库中已经声明了有数据表,则不会继续生成db.create_all()app.run(debug=True)
关于数据库锁
悲观锁,是属于数据库中的一种互斥锁机制,但是乐观锁并非真正的数据库锁。
2种锁都是数据库在应对并发操作时,防止出现资源抢夺的,基于不同人生观所实现2种解决方案。
悲观锁的基本使用:
>>> 数据库终端开始
begin; -- 开启事务
select * from db_student where student_id = 5 for update; -- 添加一把更新锁【悲观锁】
.... -- 在事务提交之前,任何第三方连接都不能修改 student_id = 5这条数据
update from db_student set age = 16 where student_id = 5;
commit; -- 提交事务<<< 数据库终端开始
悲观锁的问题:
- 提前锁定数据,形成串行化,形成阻塞,不利于性能发挥,不适用高并发场景。
- 悲观锁只能保证数据的一致性,不能保证脏数据的出现
乐观锁的出现就是为了解决悲观锁的问题。
举例:双11活动,商城里面id=5的商品的库存num=10了,现在我们要基于乐观锁和悲观锁来解决下单过程中,出现的资源抢夺现象,避免出现超卖(商品数量不能为负数)。
乐观锁:
—> begin; 开启事务
—> 先查看库存,记录当前库存 original_num=10
—> 进行下单操作,买6件
—> 付款
—> 扣除库存 update goods set num=num-6 where num=original_num and id=5; # 增加更新条件,判断库存是否还是原来
如果执行成功,则表示没有人抢,购买成功
—> commit;
如果执行失败,则表示已经有人先抢购
—> rollback;
悲观锁:
—> begin; 开启事务
—> 先给id=5的数据,加锁
select * from goods where id=5 for update;
—> 进行下单操作,买6件
—> 付款
—> 扣除库存 update from goods set num=num-6 where id=5;
—> 执行成功解锁
—> commit; 提交事务
总结
本文详述了在flask项目中结合SQLAlchemy操作mysql数据库的详细用法,非常实用,感兴趣的朋友可以一键三连,flask的高阶用法持续更新中!!!
相关文章:

【python】flask结合SQLAlchemy,在视图函数中实现对数据库的增删改查
✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…...

APIGateway的认证
APIGateway的支持的认证如下: 我们从表格中可以看到,HTTP API 不支持资源策略的功能,另外是通过JWT的方式集成Cognito的。 对于REST API则是没有显示说明支持JWT认证,这个我们可以通过Lambda 自定义的方式来实现。 所以按照这个…...
MacOS Github Push项目 精简版步骤
大白菜教程:小白菜 macOS github提交代码-CSDN博客 步骤1:git init步骤2: touch .gitignore 创建ignore文件 open .gitignore 打开ignore文件 编写ignore文件.idea/ 是文件夹的意思.git/ 也是自动生成的文件夹 也不上传.DS_St…...

Eclipse的基本使用讲解(建项目,建包,建类,写代码(基本语法))新手入门必备
目录 一.介绍eclipse 二.操作Eclipse 1.选择工作空间 2.建项目,建包,建类 1.建项目(两种) 2.建包 3.建类 三.写代码(基本语法) 1.代码操作 2.代码规范 3.代码注释 一.介绍eclipse Eclipse 是一个开放源代码的、基于Java的可扩展开发平台。就其…...

3D模型处理的并行化
今天我们将讨论如何使用 Python 多进程来处理大量3D数据。 我将讲述一些可能在手册中找到的一般信息,并分享我发现的一些小技巧,例如将 tqdm 与多处理 imap 结合使用以及并行处理存档。 那么我们为什么要诉诸并行计算呢? 使用数据有时会出现…...

盲人安全导航技巧:科技赋能让出行更自如
作为一名资深记者,长期关注并报道无障碍领域的发展动态。今日,我将聚焦盲人安全导航技巧,探讨这一主题下科技如何赋能视障人士实现更为安全、独立的出行。一款融合了实时避障、拍照识别物体及场景功能的盲人出行辅助应用叫做蝙蝠避障…...
问,由于java存在性能上,以及部分功能上的缺点,请问如何正确使用C,C++,Go,这三个语言,提升Java Web项目的性能?
拓展阅读:版本任你发,我用java8 我明白Java虽然在许多方面表现出色,但在某些特定场景下可能会遇到性能瓶颈或功能限制。为了提升Java Web项目的性能,可以考虑将C、C和Go这三种语言用于特定的组件或服务。以下是如何正确使用这些语…...
【信号与系统 - 9】傅里叶变换的性质习题
1 习题 已知 f ( t ) f(t) f(t) 的傅里叶变换为 F ( j w ) F(jw) F(jw) ,求如下信号的傅里叶变换 (1) t ⋅ f ( 3 t ) t\cdot f(3t) t⋅f(3t) 解: f ( 3 t ) ↔ 1 3 F ( j w 3 ) f(3t)\leftrightarrow \frac{1}{3}F(j\frac{w}…...
C#探索之路基础夯实篇(5):语法糖概念解析
C#探索之路基础夯实篇(5):语法糖概念解析 文章目录 C#探索之路基础夯实篇(5):语法糖概念解析1、概念定义2、Lua中的语法糖3、C#中的语法糖4、C中的语法糖5、优缺点辨析6、适用范围7、总结 从之前一开始接触lua的时候开始,开始第一次接触到语法…...

SeaTunnel 与 DataX 、Sqoop、Flume、Flink CDC 对比
产品概述 Apache SeaTunnel 是一个非常易用的超高性能分布式数据集成产品,支持海量数据的离线及实时同步。每天可稳定高效同步万亿级数据,已应用于数百家企业生产,也是首个由国人主导贡献到 Apache 基金会的数据集成顶级项目。 SeaTunnel 主要解决数据集成领域的常见问题:…...
深入理解汇编:平栈、CALL和RET指令详解
视频学习下载地址:https://pan.quark.cn/s/04e6946a803a 汇编语言以其接近硬件的特性和高效的执行速度,在系统编程、性能优化和逆向工程中占有不可或缺的地位。本文将深入探讨汇编语言中的平栈操作以及CALL和RET指令&#…...

DP4 最小花费爬楼梯
原题链接:最小花费爬楼梯_牛客题霸_牛客网 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 dp。 开一个dp数组和a数组。dp[i]表示在当前这一格所需要的费用,a数组其实就是题目中的cost数组。 因为最后要求到顶楼的最低费用&a…...
OpenXR API概览与核心组件解析
在虚拟现实(VR)和增强现实(AR)领域,OpenXR API提供了一个重要的开放标准,使得开发者能够跨多种硬件和软件平台创建兼容的应用。本文将详细解释OpenXR中的核心组件和数据结构,并探讨它们如何共同…...

安装指定版本的ant-design-vue和指定版本的@ant-design/icons-vue 图标组件包
前言: 最近在完成公司的项目时,为了兼容其他的版本,需要安装指定版本的ant-design-vue和ant-design/icons-vue 图标组件包,安装成功之后,分享如下: 安装命令: ant-design-vue: 不…...
Zynq7000系列中的休眠模式
休眠模式是在系统层面定义的,它包括将APU置于待机模式,并将多个控制器保持在无时钟的复位状态。 进入休眠模式可以大大降低功耗。在休眠模式下,大多数功能时钟组都会被关闭或断电。唯一需要保持活动的设备是一个CPU、窥探控制单元(…...
在redhat7/8平台上部署ELK7.17.18的技术方案
部署环境说明 为节省资源直接使用1台测试机模拟3节点elasticsearch服务集群做部署,在该主机上同时部署了3个elasticsearch实例、1个logstash实例、1个kibana实例、1个filebeat实例。对于生产环境,以上实例服务应该做分布式部署。 ELK-TEST1 192.168.10…...
(Chat For Al,创新Al,汇语Al助手,AiTab新标签,万能助手,LLaVA)分享6个好用的ChatGPT
目录 1、Chat For AI 2、创想AI 3、汇语AL助手...
MySQL-锁篇
文章目录 表级锁和行级锁了解吗?有什么区别?行级锁使用有什么注意事项?InnoDB有哪几类行锁?共享锁和排他锁是什么?意向锁有什么用? 锁是一种常见的并发事务的控制方式 表级锁和行级锁了解吗?有什…...

滤波器笔记(杂乱)
线性相位是时间平移,相位不失真 零、基础知识 1、用相量表示正弦量 https://zhuanlan.zhihu.com/p/345546880 https://www.zhihu.com/question/347763932/answer/1103938667 A s i n ( ω t θ ) ⇔ A e j θ ⇔ A ∠ θ Asin(\omega t\theta) {\Leftrightarrow…...

【ARFoundation自学01】搭建AR框架,检测平面点击位置克隆物体
Unity开发ARFoundation相关应用首先安装ARFoundation包 然后设置XR 1.基础AR场景框架搭建 2.一个基本的点击克隆物体到识别的平面脚本 挂在XROrigin上 脚本AppController 脚本说明书 ## 业务逻辑 AppController 脚本旨在实现一个基本的 AR 应用程序功能:用户通过…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...

C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

Linux-07 ubuntu 的 chrome 启动不了
文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了,报错如下四、启动不了,解决如下 总结 问题原因 在应用中可以看到chrome,但是打不开(说明:原来的ubuntu系统出问题了,这个是备用的硬盘&a…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...
CppCon 2015 学习:Reactive Stream Processing in Industrial IoT using DDS and Rx
“Reactive Stream Processing in Industrial IoT using DDS and Rx” 是指在工业物联网(IIoT)场景中,结合 DDS(Data Distribution Service) 和 Rx(Reactive Extensions) 技术,实现 …...
uniapp获取当前位置和经纬度信息
1.1. 获取当前位置和经纬度信息(需要配置高的SDK) 调用uni-app官方API中的uni.chooseLocation(),即打开地图选择位置。 <button click"getAddress">获取定位</button> const getAddress () > {uni.chooseLocatio…...

【Vue】scoped+组件通信+props校验
【scoped作用及原理】 【作用】 默认写在组件中style的样式会全局生效, 因此很容易造成多个组件之间的样式冲突问题 故而可以给组件加上scoped 属性, 令样式只作用于当前组件的标签 作用:防止不同vue组件样式污染 【原理】 给组件加上scoped 属性后…...