flask入门教程之数据库保存

news/2024/4/29 5:22:01/文章来源:https://blog.csdn.net/wenxiaoba/article/details/128115268

计算机操作数据时,一般是在内存中对数据进行处理,但是计算机的内存空间有限,服务器操作大量数据时,容易造成内存不足,且一旦计算机关机,则内存数据就丢失。所以我们需要将数据进行存储。

持久化(Persistence)即把数据保存到可永久保存的存储设备中(如磁盘)。持久化的主要应用是将内存中的数据存储在关系型的数据库中。当然也可以存储在磁盘文件中、XML数据文件中等。

我们学习过mysql、oracle的时候,通过sql命令去操作数据库进行数据的增删改查。对于开发人员来说,可以通过调用第三方库函数或方法,通过发送命令给数据库引擎,从而达到数据库的增删改查操作,比如pymysql库就是专门用来对mysql数据库进行操作的第三方库,pymysql的操作可以看这篇博客:pymysql的使用。

其实开发人员在进行数据库操作时,还有一个概念:ORM
ORM:Object Relational Mapping,对象关系映射。作用是在关系型数据库和对象之间做一个映射,这样在具体操作数据库的时候,就不需要再去和复杂的SQL语句打交道,只要像操作对象一样操作就可以了。简单理解就是:数据库中的每一行数据都是一个对象。

SQLAlchemy是python中最有名的ORM框架;在Flask中一般使用Flask-SQLAlchemy来操作数据库。

SQLAIchemy

Flask-SQLAlchemy的安装命令:pip install flask-sqlalchemy
官方文档:https://flask-sqlalchemy.palletsprojects.com/en/3.0.x/

首先我们先看看官方给的一个快速入门的例子:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy# 创建SQLAlchemy对象
db = SQLAlchemy()
# 创建Flask对象
app = Flask(__name__)
# 在Flask对象中,配置数据库URI信息
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///project.db"
# 初始化Flask对象中的数据库信息,即Flask对象与QLAlchemy()进行绑定
db.init_app(app)

从示例中我们可以看到在Flask中使用flask_sqlalchemy分为以下几步:

  • 步骤1:创建SQLAlchemy对象
  • 步骤2:创建Flask对象
  • 步骤3:在Flask对象中,配置数据库URI信息
  • 步骤4:初始化Flask对象中的数据库信息
  • 步骤5:使用SQLAlchemy对象对数据库进行操作

步骤3中的数据库信息配置是非常重要的,其相当于包含了数据库连接、关闭等操作,我们需要配置数据库连接信息等内容,常用配置清单如下:

配置键说明
SQLALCHEMY_DATABASE_URI用于连接数据库
SQLALCHEMY_BINDS用于多数据库连接的配置
SQLALCHEMY_TRACK_MODIFICATIONS追踪对象的修改

部分配置如SQLALCHEMY_ENGINE_OPTIONS、SQLALCHEMY_ECHO、SQLALCHEMY_RECORD_QUERIES、SQLALCHEMY_COMMIT_ON_TEARDOWN很少用到(没试过,后面有空再试),就不写了。
其他配置如SQLALCHEMY_NATIVE_UNICODE、SQLALCHEMY_POOL_SIZE、SQLALCHEMY_POOL_TIMEOUT、SQLALCHEMY_POOL_RECYCLE、SQLALCHEMY_MAX_OVERFLOW等配置键,在flask_sqlalchemy的3.0版本被移除了,这里就不过多介绍了。

SQLALCHEMY_DATABASE_URI的配置说明:
格式:dialect+driver://username:password@host:port/database

  • dialect:表示数据库类型,比如sqlite、mysql
  • driver:表示数据库引擎、驱动,比如python脚本库pymysql
  • username:连接数据库的用户名
  • password:连接数据库的密码
  • host:数据库所在IP地址
  • port:数据库监听端口
  • database:数据库名称

示例:
- 连接sqlite:sqlite:///数据库db文件所在的路径
- 连接mysql:mysql+pymysql://root:123456@127.0.0.1:3306/库名

原理:sqlalchemy其实也是通过某个驱动去修改数据库,该驱动就是dialect和driver配置的,如图:
在这里插入图片描述

表操作

方法说明
create_all()根据继承的Model的类创建表,如果表名已经存在,则不创建也不更改
drop_all()根据继承的Model的类删除对应表

关于类与表的映射:

  • 类名相当于表名
    • 如果想自定义表名,在类中定义属性:__tablename__ = 自定义的表名
    • python一般是驼峰命名的类名,表名是根据类名转为下划线连接,如class UserInfo建立的表名是user_info
  • 在类型,通过属性名 = db.Column()方法来映射成表中的字段
    • 若Column()中第一个参数默认是字段名称,字符串类型,若非字符串类型,则字段名称默认为属性名
    • 字段类型常用的有:String、Integer、Float、Double、Boolean、DateTime、Text等等,可以在python的安装目录的\Lib\site-packages\sqlalchemy\sql\sqltypes.py文件中找到支持的数据类型,官网说明:Declaring Models
    • primary_key:是否为主键,设置为True时表示该字段是主键。主键默认不能为空且自增
    • unique:是否唯一,为True时表示该字段值唯一、不重复
    • nullable:是否可为null,为True时表示可为null
    • autoincrement:是否自增,为True时表示该字段自增
    • default:默认值

注意:db是SQLAlchemy对象

示例:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy# 创建Flask对象
app = Flask(__name__)
# 在Flask对象中,配置数据库信息
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:wen@127.0.0.1:3306/test?charset=utf8"
# app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = True
# 初始化Flask对象中的数据库信息
# db = SQLAlchemy(app)
db = SQLAlchemy()
db.init_app(app)class UserInfo(db.Model):id = db.Column("user_id", db.Integer, primary_key=True)name = db.Column(db.String(50))class SubjectManagement(db.Model):__tablename__ = "subject_info"subject_name = db.Column(db.String(25))subject_id = db.Column(db.Integer, primary_key=True)if __name__ == "__main__":# 根据官网指示,需要在app_context()下进行表的创建和删除with app.app_context():# 创建表db.create_all()# 删除表# db.drop_all()

在这里插入图片描述

表数据操作

方法描述
db.session.add(类对象)添加单条数据
db.session.add_all(instances)一次性添加多条数据。 instances一般是列表、元组等类型的数据
db.session.commit()将数据提交(如果对数据库有修改,则需要提交才能在数据库中生效,未commit前都是暂存在暂存区
db.session.close()关闭session(记得关闭session,不然太多暂存区会占用内存空间)
类.query.filter_by(属性名=值).filter_by(属性名=值).xxxfilter_by表示根据条件进行过滤,多个条件就多个filter_by方法(注意:是按照属性名不是按照字段名,底层会将属性名识别成字段名)
类.query.filter_by(属性名=值).first()获取查询结果的第一条数据,返回类的对象
类.query.filter_by(属性名=值).all()获取查询结果的所有数据,返回一个列表,列表中元素是类的对象

注意:db是SQLAlchemy对象

添加数据

示例:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy# 创建Flask对象
app = Flask(__name__)
# 在Flask对象中,配置数据库信息
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:wen@127.0.0.1:3306/test?charset=utf8"
# app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = True
db = SQLAlchemy()
db.init_app(app)class Person(db.Model):id = db.Column("user_id", db.Integer, primary_key=True)name = db.Column(db.String(50), nullable=False)gender = db.Column(db.String(1))if __name__ == "__main__":with app.app_context():p1 = Person(id=1, name="张三", gender="男")p2 = Person(id=2, name="李四", gender="女")p3 = Person(id=3, name="王五", gender="男")db.session.add(p1)db.session.add_all((p2, p3))db.session.commit()db.session.close()

执行脚本,查询数据库数据,结果如下:
在这里插入图片描述

查询数据

示例:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import select, create_engine# 创建Flask对象
app = Flask(__name__)
# 在Flask对象中,配置数据库信息
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:wen@127.0.0.1:3306/test?charset=utf8"
# app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = True
db = SQLAlchemy()
db.init_app(app)class Person(db.Model):id = db.Column("user_id", db.Integer, primary_key=True)name = db.Column(db.String(50), nullable=False)gender = db.Column(db.String(1))if __name__ == "__main__":with app.app_context():res1 = Person.query.filter_by(gender="男").first()print("---------------first()---------------")print("数据类型:", type(res1))print(res1.id, res1.name, res1.gender)res2 = Person.query.filter_by(gender="男").all()print("\n---------------all()---------------")print(f"数据类型:{type(res2)},元素类型:{type(res2[0])}")print(res2)for r in res2:print(r.id, r.name, r.gender)res3 = Person.query.filter_by(gender="男").filter_by(id=3).all()print("\n---------------多个过滤条件---------------")print(f"数据类型:{type(res3)},元素类型:{type(res3[0])}")print(res3)for r in res3:print(r.id, r.name, r.gender)

数据库内容为:
在这里插入图片描述
执行结果为:

---------------first()---------------
数据类型: <class '__main__.Person'>
1 张三 男---------------all()---------------
数据类型:<class 'list'>,元素类型:<class '__main__.Person'>
[<Person 1>, <Person 3>, <Person 4>]
1 张三 男
3 王五 男
4 弓长张 男---------------多个过滤条件---------------
数据类型:<class 'list'>,元素类型:<class '__main__.Person'>
[<Person 3>]
3 王五 男

修改数据

示例:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import select, create_engine# 创建Flask对象
app = Flask(__name__)
# 在Flask对象中,配置数据库信息
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:wen@127.0.0.1:3306/test?charset=utf8"
# app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = True
db = SQLAlchemy()
db.init_app(app)class Person(db.Model):id = db.Column("user_id", db.Integer, primary_key=True)name = db.Column(db.String(50), nullable=False)gender = db.Column(db.String(1))if __name__ == "__main__":with app.app_context():# 方式一:查询数据,修改数据对象的属性,提交sessionres = Person.query.filter_by(id=2).first()res.name = "力士"db.session.commit()db.session.close()# 方式二:给定查询条件并直接update操作,提交sessionres = Person.query.filter_by(id=4)res.update({"gender": "女", "name": "章双双"})db.session.commit()db.session.close()

在这里插入图片描述

删除数据

示例:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import select, create_engine# 创建Flask对象
app = Flask(__name__)
# 在Flask对象中,配置数据库信息
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:wen@127.0.0.1:3306/test?charset=utf8"
# app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = True
db = SQLAlchemy()
db.init_app(app)class Person(db.Model):id = db.Column("user_id", db.Integer, primary_key=True)name = db.Column(db.String(50), nullable=False)gender = db.Column(db.String(1))if __name__ == "__main__":with app.app_context():# 方式一:查询数据并删除,提交sessionres = Person.query.filter_by(id=2).first()db.session.delete(res)db.session.commit()db.session.close()# 方式二:给定查询条件直接delete(),提交sessionres = Person.query.filter_by(id=4)res.delete()db.session.commit()db.session.close()

执行结果:
在这里插入图片描述

ORM优缺点

从以上的学习中可以了解到:
优势:

  • 隐藏了数据访问细节
  • ORM使我们构造固化数据结果变得非常简单

缺点:

  • 性能下降,添加了关联操作,性能不可比秒的会下降
  • 无法解决特别复杂的数据库操作

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

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

相关文章

Java 基础数据类型占用内存空间和字符串编码简介(二)

Java 基础数据类型占用内存空间简介一 计算机简介1.基本概念2.CPU 三级缓存3.本机参数查看二 数据占用内存情况1.多线程Demo2.结果解析1.直接计算2.volatile 计算3.缓存行填充一 计算机简介 结合多线程计算机的硬件&#xff0c;从侧面理解数据存储如何影响我们的程序 1.基本概…

门面/外观模式

一、门面模式 1、定义 门面模式&#xff08;Facade Pattern&#xff09;又称作外观模式&#xff0c;是指提供一个统一的接口&#xff0c;用来访问子系统中的一群接口&#xff0c;属于结构型设计模式。 门面模式的主要特征是定义了一个高层接口&#xff0c;让子系统更容易使用。…

自然语言处理NLP——ERNIE-M:基于回译机制的“预训练-微调”多语言模型

目录 系列文章目录 一、背景介绍 1.多语言任务 1.1 多语言任务定义 1.2 多语言任务难题 2.多语言模型 2.1 多语言模型定义与原理 2.2 多语言模型困难 3.论文简介 3.1 背景与开发动机 3.2 论文梗概 3.3 论文贡献与成就 二、相关工作 1.预训练方法 1.1 预训练方法…

Tomcat的安装、在idea中的使用以及创建Web项目

目录Tomcat的安装Tomcat运行Tomcat在idea中的使用创建Web项目最后Tomcat的安装 Tomcat的官网: https://tomcat.apache.org/ 从官网上可以下载对应的版本进行使用。 下载windows64位&#xff0c;版本自行选择。 下载好之后找到压缩包进行解压&#xff0c;注意目录不要有中文且…

1. 一些截图方法的比较;2. 将截图直接转换为PDF并拼接,与插入Word后再转换为PDF的对比

1. 一些截图方法的比较 1.1. 有时候当某个软件没有导出功能&#xff0c;或者导出功能受限&#xff0c;比如 tableau public&#xff0c;但又需要获取展示出的可视化信息时&#xff0c;就需要用到截图。如果这些截图还要用在正式文档中&#xff0c;就需要是高清的&#xff0c;至…

[附源码]Python计算机毕业设计SSM篮球馆预约小程序(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

TypeScript(TS)基础内容详细介绍

目录 一、TypeScript概念 二、TypeScript特点 三、开发环境配置 四、初识ts 五、TypeScript类型声明 1、any&#xff1a; 2、number数字类型 3 string字符串类型 4 boolean布尔类型 表示逻辑值&#xff1a;true 和 false。 5 数组类型 6 元组类型 7 enum枚举类型…

Java8 函数式编程【基础篇】

Java 8是Java在保持向后兼容的前提下首次迈出重要一步&#xff0c;相比之前&#xff0c;不再是只对类库的改良&#xff0c;在编写复杂的集合处理、并行化执行、代码简洁度等方面都有颠覆性的提升。本文将探索和理解函数式编程的含义&#xff0c;以及它在Java 8中的实现。 一、…

全光谱台灯对孩子有伤害吗?儿童用台灯的好处和坏处是什么

全光谱台灯是指灯光色谱丰富度与太阳光一般全面的台灯&#xff0c;这样的灯光照射下的任何物体&#xff0c;不但颜色丰富多彩&#xff0c;而且极其真实&#xff0c;无限接近太阳光下的真实色彩&#xff0c;对人眼舒适度有巨大的提升&#xff0c;所以全光谱台灯不但对孩子无害&a…

【文件I/O】标准IO:库函数

标准IO&#xff1a;库函数一、基本概念1.文件类型2.标准I/O介绍3.流的概念4.文本流和二进制流5.流的缓冲类型6.标准I/O流&#xff08;stdin、stdout、stderr&#xff09;二、标准I/O函数1.fopen、fclose、errrno、strerror、perror&#xff08;打开、关闭文件&#xff0c;输出错…

小程序开发音视频问题汇总及解决方案

目录 问题一&#xff1a;开发音视频&#xff0c;必用的两个小程序组件live-player和live-pusher&#xff0c;他们做什么用的&#xff0c;怎么才能使用&#xff1f; 问题二&#xff1a;一个页面只能插入一个 问题三&#xff1a;真机调试图片预览及视频全屏无反应 问题四&am…

在vue项目中下载swiper出现:Do not use ‘new’ for side effects报错问题

我报错的情况是&#xff1a;我在单文件组件vue文件中使用new Swiper&#xff0c;报了两个错误&#xff0c;图示&#xff1a; 第一个错误是&#xff1a;‘Swiper’ is not defined 第二个错误是&#xff1a;Do not use ‘new’ for side effects 解决办法&#xff1a; &#x…

5G无线技术基础自学系列 | MU-MIMO原理

素材来源&#xff1a;《5G无线网络规划与优化》 一边学习一边整理内容&#xff0c;并与大家分享&#xff0c;侵权即删&#xff0c;谢谢支持&#xff01; 附上汇总贴&#xff1a;5G无线技术基础自学系列 | 汇总_COCOgsta的博客-CSDN博客 MU-MIMO是指多个用户在上下行数据传输时…

【Linux】命令

常用命令 帮助&#xff08;Manual Pages&#xff0c;Manual&#xff1a;手册&#xff0c;特指参考文件&#xff09; man man <command_name> 打开目录&#xff08;change directory&#xff09; cd /etc/ cd /home 查看当前所在目录 pwd 创建一个名为 file 的文件&…

[附源码]计算机毕业设计JAVA校园共享单车系统

[附源码]计算机毕业设计JAVA校园共享单车系统 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybati…

二、【React拓展】懒加载 lazy

文章目录1、适用点2、汇总1、适用点 懒加载往往配合路由一起使用&#xff0c;此处修改的项目是 二、【React-Router5】路由的基本使用 中的项目 首先从react中引入lazy import { lazy } from react 修改引入路由组件的写法 // import About from ./pages/About // import Home…

SequoiaDB湖仓一体分布式数据库2022.11月刊

本月看点速览 产品能力再获认可&#xff0c;入围多个榜单、报告 ‍精彩亮相2022沙丘大会湖仓一体专场 实力吸睛&#xff0c;获多家权威媒体关注与报道 生态圈不断扩大&#xff0c;与6家合作伙伴完成互认证 青杉计划2023进行中&#xff0c;一起攀登更高的“杉” 产品能力再获…

pip 安装 livetest 失败

pip 安装 livetest 失败1. 现象2. 解决方案(1) 下载(2) 移动并解压(3) 修改文件1) livetest-0.5/livetest/__init__.py2) livetest-0.5/setup.py3) livetest-0.5/test/test_select.py(4) 运行安装4. 验证1. 现象 pip 安装 livetest 失败 2. 解决方案 (1) 下载 官网下载 liv…

09-13-Hbase-shell入门操作

09-Hbase-shell入门操作&#xff1a; HBase Shell 操作 DDL基本操作 1&#xff0e;进入 HBase 客户端命令行 [roothadoop102 hbase-1.3.1]# bin/hbase shell 2&#xff0e;查看帮助命令 hbase(main):001:0> help 3&#xff0e;查看当前数据库中有哪些表 hbase(main):0…

网页添加灰色滤镜

网页添加灰色滤镜 b站的灰色滤镜 我校的灰色滤镜 CSDN的灰色滤镜 自己调制css主题,给网页加上滤镜. 更快捷的,可以在可以调制css的浏览器插件中加上滤镜,只要开启插件就会自动修改网站滤镜 以darkreader为例打开其开发者工具 *INVERT .jfk-bubble.gtx-bubble .captcheck_a…