flask入门教程之数据库保存

news2024/11/25 12:34:52

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

持久化(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():
        # 方式一:查询数据,修改数据对象的属性,提交session
        res = Person.query.filter_by(id=2).first()
        res.name = "力士"
        db.session.commit()
        db.session.close()

        # 方式二:给定查询条件并直接update操作,提交session
        res = 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():
        # 方式一:查询数据并删除,提交session
        res = Person.query.filter_by(id=2).first()
        db.session.delete(res)
        db.session.commit()
        db.session.close()

        # 方式二:给定查询条件直接delete(),提交session
        res = Person.query.filter_by(id=4)
        res.delete()
        db.session.commit()
        db.session.close()

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

ORM优缺点

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

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

缺点:

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

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

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

相关文章

HTTP协议发展史

简介 Hyper Text Transfer Protocol&#xff08;超文本传输协议&#xff09;,是用于从万维网&#xff08;WWW:World Wide Web &#xff09;服务器传输超文本到本地浏览器的传送协议。是互联网上应用最为广泛的一种网络协议。所有的 WWW 文件都必须遵守这个标准。 超文本传输 …

地图数据设计(四):地图比例尺

前言 比例尺作为地图数学基础的组成部分之一&#xff0c;表示了地图的空间尺度&#xff0c;是地图精度和内容详尽程度的决定因素。今天的文章将从比例尺的基本概念、常见比例尺参数以及SuperMap iDesktopX中比例尺设置三个方面展开。 1 比例尺的基本概念 1.1 定义 一般来说&am…

Day16-购物车页面-商品列表修改购物车商品的勾选状态

提纲挈领&#xff1a; 我的操作&#xff1a; 1》当用户点击 radio 组件&#xff0c;希望修改当前商品的勾选状态&#xff0c;此时用户可以为 my-goods 组件绑定 radio-change 事件&#xff0c;从而获取当前商品的 goods_id 和 goods_state&#xff1a; 定义 radioChangeHandle…

达梦数据库备份策略

文章目录一、达梦数据库备份策略1.1 开启归档模式1.1.1 联机配置本地归档1.1.2 脱机配置本地归档1.2 启动DMAP服务1.2.1 启动DMAP1.3 物理备份1.3.1 联机备份(1) 数据库备份(2) 表空间备份(3) 表备份(4) 备份归档1.3.2 脱机备份(1) 启动DMRMAN(2) 备份数据库1.4 物理备份还原1.…

【Linux】命令

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

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…

美国硅基和宽禁带半导体供应链竞争力剖析

&#x1f446;扫描上方二维码&#xff0c;报名参与研讨会直播&#xff0c;福利多多~ 前言 本文概述了半导体供应链&#xff0c;包括传统半导体&#xff08;即硅基&#xff09;和 宽禁带&#xff08;WBG&#xff0c;Wide Bandgap&#xff09; 半导体&#xff0c;并深入探讨了宽禁…

[附源码]JAVA毕业设计高校医务管理系统(系统+LW)

[附源码]JAVA毕业设计高校医务管理系统&#xff08;系统LW&#xff09; 目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术…

[附源码]Python计算机毕业设计Django动物保护协会网站

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

[激光原理与应用-26]:《激光原理与技术》-12- 激光产生技术-短脉冲、超短脉冲、调Q技术、锁模技术

目录 第1章 什么是激光脉冲 1.1 什么是激光脉冲&#xff08;时间能量维度&#xff09; 1.2 激光脉冲的好处 1.3 巨脉冲激光&#xff08;能量维度&#xff09; 1.4 什么是激光短脉冲与超短脉冲激光&#xff08;时间维度&#xff09; 1.5 长脉冲宽度缺点与短脉冲的优点 1.…

小白学流程引擎-FLowable(三) —流程设计器Flowable UI

一、如何绘制BPMN文件 上文讲到了通过流程定义BPMN文件即可让流程流转起来&#xff0c;并执行来几个核心的功能测试。但是那个看起来复杂的BPMN.xml文件的内容手敲起来有点困难&#xff0c;那么实际真实的场景是什么&#xff0c;或者是怎么完成流程图BPMN文件的绘制呢&#xf…

开源笔记leanote搭建记录

一、leanote 版本二进制编译好的文件&#xff0c;github下载 leanote-linux-386-v2.6.1.bin.tar.gz 二、mongodb docker 部署 版本 4.4 备注&#xff1a;刚开始用5.0.14 版本&#xff0c;启动程序&#xff0c;数据库验证报错 后有用3.0版本&#xff0c;导入初始化数据失败&…

企业网站的建设有哪些事项需要注意呢?

企业网站建设的意义&#xff0c;不仅在于提高了企业的知名度&#xff0c;更重要的是让外界了解企业的产品、服务。随着互联网技术的不断发展&#xff0c;互联网逐渐成为中国最具活力、变化最快的行业。对于网站建设公司来说&#xff0c;这也是一个巨大的市场空间&#xff0c;但…

新买的笔记本电脑分区,笔记本分区分错了怎么重新分

用户新购买的一部笔记本电脑&#xff0c;打开电脑一看就傻眼了&#xff0c;电脑中只有一个内存为1.8T的C盘&#xff0c;像是D盘、E盘、F盘都不知道在哪里&#xff0c;他赶紧咨询旗舰店的客服&#xff0c;客服告知他&#xff1a;“需要对磁盘分区后&#xff0c;才能有D盘、E盘和…

ROS SMACH个人学习记录

ROS SMACH学习个人记录SMACH关于抢占一些TipsSMACH缺点个人的结论本文仅为个人学习记录&#xff0c;结论正确性待考究。欢迎大家讨论SMACH 关于抢占 抢占需要在并发容器里面实现&#xff0c;并发容器里面包含多个状态&#xff0c;我们分成两类&#xff1a;抢占状态与被抢占状…

APK 是怎么来的?- Android 构建流程解析

一、 APK 组成解析 在开始解析 Android 构建流程之前&#xff0c;我们先来看下构建的最终产物 APK 的整体组成 APK 主要由五个部分组成&#xff0c;分别是&#xff1a; Dex&#xff1a;.class 文件处理后的产物&#xff0c;Android 系统的可执行文件 Resource&#xff1a;资源…

Android S(31) APP 页面绘制流程

接上一篇app 启动流程调用OnCreate方法&#xff0c;页面布局绘制进入setContentView 1、加载布局setContentView() 这里getWindow()直接返回mWindow&#xff0c;这个早在onCreate 调用前Activity#attach里面完成初始化。 进入attach方法&#xff0c;构建一个窗体对象PhoneWind…

[附源码]SSM计算机毕业设计疫情防控下高校教职工健康信息管理系统JAVA

项目运行 环境配置&#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…

Docker Cgroups资源控制

目录 一、cgroups简介 cgroups有四大功能&#xff1a; 二、cpu时间片的概念 三、对CPU使用的限制 1 设置CPU使用率上限 &#xff08;1&#xff09;查看容器的默认CPU使用限制 2 设置CPU资源占用比&#xff08;设置多个容器时才有效&#xff09; 1&#xff09;创建两个容器…

回归商业初心,宝尊电商“深耕广拓”缔造品牌电商有质增长

今年来&#xff0c;受疫情、通胀、能源等因素影响&#xff0c;全球市场都经历了不同程度的“震荡”。 寒气传递之间&#xff0c;电商行业开始摸索后疫情时代的前进之路。随着财报季来临&#xff0c;市场开始期待从各赛道标杆企业财报中看出行业走势。 11月29日&#xff0c;“…