【Flask】Flask数据库

【Flask】Flask数据库

  • 1.概述
  • 2.使用Flask-SQLAlchemy管理数据库
  • 3.定义模型
  • 4.关系
  • 5.数据库操作
    • 创建表
    • 插入行
    • 修改行
    • 删除行
    • 查询行

1.概述

大多数的数据库引擎都有对应的 Python 包,包括开源包和商业包。Flask 并不限制你使用何种类型的数据库包,因此可以根据自己的喜好选择使用 MySQL、Postgres、SQLite、Redis、MongoDB 或者 CouchDB

如果这些都无法满足需求,还有一些数据库抽象层代码包供选择,例如 SQLAlchemy 和MongoEngine。你可以使用这些抽象包直接处理高等级的 Python 对象,而不用处理如表、文档或查询语言此类的数据库实体

抽象层,也称为对象关系映射(ORM)或对象文档映射(ODM),在用户不知觉的情况下把高层的面向对象操作转换成低层的数据库指令,ORM 和 ODM 把对象业务转换成数据库业务会有一定的损耗,但在一般情况下,ORM 和 ODM 对生产率的提升远远超过了这一丁点儿的性能降低


2.使用Flask-SQLAlchemy管理数据库

Flask-SQLAlchemy 是一个 Flask 扩展,简化了在 Flask 程序中使用 SQLAlchemy 的操作。SQLAlchemy 是一个很强大的关系型数据库框架,支持多种数据库后台。SQLAlchemy 提供了高层 ORM,也提供了使用数据库原生 SQL 的低层功能。

1、pip安装

pip install flask-sqlalchemy

2、在 Flask-SQLAlchemy 中,数据库使用 URL 指定。最流行的数据库引擎采用的数据库 URL格式如下:

  • MySQL:mysql://username:password@hostname/database
  • PostgreSQL:postgresql://username:password@hostname/database
  • SQLite (Unix):sqlite:absolute/path/to/database
  • SQLite (Windows):sqlite:///c:/absolute/path/to/database

配置数据库:

app = Flask(__name__)
basedir = os.path.abspath(os.path.dirname(__file__))
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'data.sqlite')
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = Truedb = SQLAlchemy(app)

db 对象是 SQLAlchemy 类的实例,表示程序使用的数据库,同时还获得了 Flask-SQLAlchemy提供的所有功能


3.定义模型

模型这个术语表示程序使用的持久化实体。在 ORM 中,模型一般是一个 Python 类,类中的属性对应数据库表中的列,如下面的例子,定义 Role 和 User 模型:

class Role(db.Model):__tablename__ = 'roles'id = db.Column(db.Integer, primary_key=True)name = db.Column(db.String(64), unique=True)def __repr__(self):return '<Role %r>' % self.nameclass User(db.Model):__tablename__ = 'users'id = db.Column(db.Integer, primary_key=True)username = db.Column(db.String(64), unique=True, index=True)def __repr__(self):return '<User %r>' % self.username

类变量 __tablename__ 定义在数据库中使用的表名。如果没有定义 __tablename__,Flask-SQLAlchemy 会使用一个默认名字,但默认的表名没有遵守使用复数形式进行命名的约定,所以最好由我们自己来指定表名。其余的类变量都是该模型的属性,被定义为 db.Column 类的实例

db.Column 类构造函数的第一个参数是数据库列和模型属性的类型:

  • Integer: 普通整数,一般是 32 位有符号整数。
    • Python 类型: int
  • SmallInteger: 取值范围小的整数,一般是 16 位有符号整数。
    • Python 类型: int
  • BigInteger: 不限制精度的整数。
    • Python 类型: intlong
  • Float: 浮点数。
    • Python 类型: float
  • Numeric: 定点数。
    • Python 类型: decimal.Decimal
  • String: 变长字符串。
    • Python 类型: str
  • Text: 变长字符串,对较长或不限长度的字符串做了优化。
    • Python 类型: str
  • Unicode: 变长 Unicode 字符串。
    • Python 类型: unicode
  • UnicodeText: 变长 Unicode 字符串,对较长或不限长度的字符串做了优化。
    • Python 类型: unicode
  • Boolean: 布尔值。
    • Python 类型: bool
  • Date: 日期。
    • Python 类型: datetime.date
  • Time: 时间。
    • Python 类型: datetime.time
  • DateTime: 日期和时间。
    • Python 类型: datetime.datetime
  • Interval: 时间间隔。
    • Python 类型: datetime.timedelta
  • Enum: 一组字符串。
    • Python 类型: str
  • PickleType: 自动使用 Pickle 序列化。
    • Python 类型: 任何 Python 对象
  • LargeBinary: 二进制文件。
    • Python 类型: str

SQLAlchemy 中常用的列选项及其含义:

  • primary key: 如果设为 True,这列就是表的主键。
  • unique: 如果设为 True,这列不允许出现重复的值。
  • index: 如果设为 True,为这列创建索引,提升查询效率。
  • nullable: 如果设为 True,这列允许使用空值;如果设为 False,这列不允许使用空值。
  • default: 为这列定义默认值。

虽然没有强制要求,但这两个模型都定义了 __repr()__ 方法,返回一个具有可读性的字符串表示模型,可在调试和测试时使用


4.关系

关系型数据库使用关系把不同表中的行联系起来,一对多关系在模型类中的表示方法如示例所示:

class Role(db.Model):# roles表# 其他列的定义...users = db.relationship('User', backref='role')class User(db.Model):# users表# 其他列的定义...role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))

关系使用 users 表中的外键连接了两行。添加到 User 模型中的 role_id 列被定义为外键,就是这个外键建立起了关系。传给 db.ForeignKey() 的参数’roles.id’ 表明,这列的值是 roles 表中行的 id 值

添加到 Role 模型中的 users 属性代表这个关系的面向对象视角。对于一个 Role 类的实例,其 users 属性将返回与角色相关联的用户组成的列表。db.relationship() 的第一个参数表明这个关系的另一端是哪个模型。db.relationship() 中的 backref 参数向 User 模型中添加一个 role 属性,从而定义反向关系。这一属性可替代 role_id 访问 Role 模型

这样一来,当你查询一个角色对象时,你可以通过 role.users 属性访问与该角色相关联的所有用户对象,而且当你查询一个用户对象时,你也可以通过 user.role 属性访问该用户所属的角色对象。这种关系的建立使得在查询时能够方便地获取到相关联的对象,提高了数据的访问效率和代码的可读性

定义关系时常用的配置选项:

  • backref: 在关系的另一个模型中添加反向引用,以便从另一个方向访问这个关系。
  • primaryjoin: 明确指定两个模型之间使用的联结条件。通常在模棱两可的关系中需要指定。
  • lazy: 指定如何加载相关记录。可选值有 select(首次访问时按需加载)、immediate(源对象加载后就加载)、joined(加载记录,但使用联结)、subquery(立即加载,但使用子查询)、noload(永不加载)和 dynamic(不加载记录,但提供加载记录的查询)。
  • uselist: 如果设为 False,不使用列表,而使用标量值指定关系中记录的排序方式。常用于一对一关系中。
  • order_by: 指定关系中记录的排序方式。
  • secondary: 指定多对多关系中关系表的名字。
  • secondaryjoin: 在 SQLAlchemy 无法自行决定时,指定多对多关系中的二级联结条件。

除了一对多之外,还有几种其他的关系类型。一对一关系可以用前面介绍的一对多关系表示,但调用 db.relationship() 时要把 uselist 设为 False,把“多”变成“一”。多对一关系也可使用一对多表示,对调两个表即可,或者把外键和 db.relationship() 都放在“多”这一侧。最复杂的关系类型是多对多,需要用到第三张表,这个表称为关系表。


5.数据库操作

创建表

我们要让 Flask-SQLAlchemy 根据模型类创建数据库。方法是使用db.create_all()函数:

db.create_all()

如果你查看程序目录,会发现新建了一个名为 data.sqlite 的文件。这个 SQLite 数据库文件的名字就是在配置中指定的。如果数据库表已经存在于数据库中,那么db.create_all()不会重新创建或者更新这个表

连接data.sqlite,可以看到创建好的roles表和users表:

插入行

在这个示例中,我们定义了一个名为 User 的数据库模型类,并创建了一个名为 new_user 的新用户对象。我们使用 db.session.add() 将新用户对象添加到会话中,并使用 db.session.commit() 提交会话,将数据插入到数据库中

@app.route('/', methods=['GET', 'POST'])
def index():new_user = User(username='john')db.session.add(new_user)db.session.commit()return render_template('index.html')

在数据库中可以看到插入的新数据(主键自动递增):

修改行

要修改已存在的用户信息,你可以首先查询到该用户对象,然后修改其属性,最后提交会话:

@app.route('/', methods=['GET', 'POST'])
def index():user_to_modify = User.query.filter_by(username='john').first()user_to_modify.username = 'tom'db.session.commit()return render_template('index.html')

在数据库中可以看到修改的新数据:

删除行

数据库会话还有个 delete() 方法,删除与插入和更新一样,提交数据库会话后才会执行:

@app.route('/', methods=['GET', 'POST'])
def index():user_to_delete = User.query.filter_by(username='tom').first()db.session.delete(user_to_delete)db.session.commit()return render_template('index.html')

在数据库中可以看到,用户已经被删除了:

查询行

Flask-SQLAlchemy 为每个模型类都提供了 query 对象。最基本的模型查询是取回对应表中的所有记录:

@app.route('/', methods=['GET', 'POST'])
def index():users = User.query.all()for user in users:print("id:", user.id)print("username:", user.username)return render_template('index.html')


使用过滤器可以配置 query 对象进行更精确的数据库查询:

@app.route('/', methods=['GET', 'POST'])
def index():user = User.query.filter_by(id=1).first()print(user.username)return render_template('index.html')

若要查看 SQLAlchemy 为查询生成的原生 SQL 查询语句,只需把 query 对象转换成字符串:

@app.route('/', methods=['GET', 'POST'])
def index():print(User.query.filter_by(id=1))return render_template('index.html')

在 query 对象上调用的常用过滤器。完整的列表如下:

  • filter():把过滤器添加到原查询上,返回一个新查询。可以使用各种条件来过滤结果集,比如相等、不等、大于、小于、包含等等。
  • filter_by():把等值过滤器添加到原查询上,返回一个新查询。通常用于根据指定的属性值来过滤结果集。
  • limit():使用指定的值限制原查询返回的结果数量,返回一个新查询。可以控制查询结果的数量,常用于分页查询。
  • offset():偏移原查询返回的结果,返回一个新查询。通常与 limit() 结合使用,用于分页查询中指定偏移量。
  • order_by():根据指定条件对原查询结果进行排序,返回一个新查询。可以按照一个或多个属性进行升序或降序排序。
  • group_by():根据指定条件对原查询结果进行分组,返回一个新查询。通常与聚合函数一起使用,用于统计分组数据。

all() 之外,还有其他方法能触发查询执行,列表如下:

  • all():以列表形式返回查询的所有结果。返回一个包含查询结果的列表。
  • first():返回查询的第一个结果,如果没有结果,则返回 None。
  • first_or_404():返回查询的第一个结果,如果没有结果,则终止请求,返回 404 错误响应。
  • get():返回指定主键对应的行,如果没有对应的行,则返回 None。常用于根据主键获取单个对象。
  • get_or_404():返回指定主键对应的行,如果没有找到指定的主键,则终止请求,返回 404 错误响应。
  • count():返回查询结果的数量。
  • paginate():返回一个 Paginate 对象,它包含指定范围内的结果。通常用于分页查询,可以指定返回结果的页数和每页的数量。

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

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

相关文章

PhotoMaker部署文档

一、介绍 PhotoMaker&#xff1a;一种高效的、个性化的文本转图像生成方法&#xff0c;能通过堆叠 ID 嵌入自定义逼真的人类照片。相当于把一张人的照片特征提取出来&#xff0c;然后可以生成你想要的不同风格照片&#xff0c;如写真等等。 主要特点&#xff1a; 在几秒钟内…

前端登录页面验证码

首先&#xff0c;在el-form-item里有两个div&#xff0c;各占一半&#xff0c;左边填验证码&#xff0c;右边生成验证码 <el-form-item prop"code"><div style"display: flex " prop"code"><el-input placeholder"请输入验证…

小赢卡贷公益行:乡村振兴与多元公益并进

在金融科技的浪潮中&#xff0c;小赢卡贷不仅以其创新的金融产品和服务赢得了市场的广泛认可&#xff0c;更以其背后的公益之心&#xff0c;积极履行社会责任&#xff0c;传递着温暖与希望。小赢公益基金会&#xff0c;作为小赢卡贷社会责任的延伸&#xff0c;主要聚焦于乡村振…

Hi3061M开发板——系统时钟频率

这里写目录标题 前言MCU时钟介绍PLLCRG_ConfigPLL时钟配置另附完整系统时钟结构图 前言 Hi3061M使用过程中&#xff0c;AD和APT输出&#xff0c;都需要考虑到时钟频率&#xff0c;特别是APT&#xff0c;关系到PWM的输出频率。于是就研究了下相关的时钟。 MCU时钟介绍 MCU共有…

unix中如何申请进程调度的优先级

一、前言 unix系统中&#xff0c;进程的调度是由内核决定的。在一个系统中&#xff0c;进程的优先级越高&#xff0c;表示其在一定时间中占用cpu的时间越久。本文将介绍unix系统如何修改以及获取进程的优先级。 二、nice值 nice值是unix系统中用于表征进程优先级的一个参数。…

ssh -T git@github.com 出现异常

上传代码到github 私有仓库 步骤 1. 生成 SSH Key&#xff08;如果没有&#xff09; 打开终端并运行&#xff1a; bash 复制 ssh-keygen -t ed25519 -C "your_emailexample.com"按提示保存密钥文件和设置密码短语&#xff08;可选&#xff09;。默认位置是 ~/.…

recyclerView(kotlin)

recyclerView的优点 使用viewHolderRecycledViewPool的方式复用资源&#xff0c;提高性能利用LayoutManager&#xff0c;可根据不同需求使用不同的布局&#xff0c;且可以方便使用对应布局提供的方法&#xff0c;如快速定位item等。RecyclerView 提供了一个 ItemAnimator 接口…

计算机毕业设计Django+Vue.js豆瓣图书推荐系统 图书评论情感分析 豆瓣图书可视化大屏 豆瓣图书爬虫 数据分析 图书大数据 大数据毕业设计 机器学习

《DjangoVue.js豆瓣图书推荐系统》开题报告 一、研究背景与意义 1. 研究背景 随着数字化时代的来临&#xff0c;图书资源日益丰富&#xff0c;用户面临着信息过载的问题。如何在海量图书中快速找到符合个人兴趣和需求的书籍成为了亟待解决的问题。传统的图书检索方式往往基于…

OmniDrive 论文学习

OmniDrive: A Holistic LLM-Agent Framework for Autonomous Driving with 3D Perception, Reasoning and Planning 解决了什么问题&#xff1f;相关工作端到端自动驾驶多模态语言模型&#xff08;MLLMs&#xff09;Drive LLM-Agents and BenchmarksDrive LLM-Agents基准测试 提…

柔性作业车间调度(FJSP)

1.1 调度问题的研究背景 生产调度是指针对一项可分解的工作(如产品制造),在尽可能满足工艺路线、资源情况、交货期等约束条件的前提下,通过下达生产指令,安排其组成部分(操作)所使用的资源、加工时间及加工的先后顺序,以获得产品制造时间或成本最优化的一项工作。 一般研究车间…

MySQL 日志 - Binlog

文章目录 binlog 的格式mysqbinlog 工具SHOW binlog events;binlog 和 redo log 对比 https://dev.mysql.com/doc/refman/8.4/en/binary-log.html binlog 全称 BinaryLog&#xff0c;是 MySQL 数据库中用于记录所有更改数据库状态的事件的日志文件。它主要用于以下几个目的&am…

【hot100-java】二叉树中的最大路径和

二叉树篇 easy. /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, TreeNode right) {* …

考试宝 逆向 分析

声明: 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 有相关问题请第一时间头像私信联系我…

Ping32引领数据防泄漏新潮流:智能、高效、安全

在当今数字化迅猛发展的时代&#xff0c;企业面临着日益严峻的数据安全挑战。数据泄漏事件频发&#xff0c;不仅损害企业声誉&#xff0c;还可能导致巨额的经济损失。为此&#xff0c;Ping32以其创新的数据防泄漏解决方案&#xff0c;正在引领行业新潮流。其技术特点可概括为“…

集师知识付费小程序:打造培训机构在线教育的金字招牌 集师知识付费系统 集师知识付费小程序 集师知识服务系统 集师线上培训系统 集师线上卖课小程序

在数字化浪潮的推动下&#xff0c;在线教育已成为教育领域的热门话题。而在众多在线教育平台中&#xff0c;集师知识付费小程序凭借其独特的定位和创新的模式&#xff0c;成功为培训机构打造了一张闪亮的在线教育金字招牌。 集师知识付费小程序&#xff0c;是一个集课程展示、…

从零开始学习Vue3

1、Vue3特点&#xff1a;更多的API特性&#xff1b;体积更小&#xff0c;速度更快&#xff1b;解决遗留问题&#xff1b;更加强壮。 2、通过全面学习Vue3&#xff0c;新手与老手的收获&#xff1a; 新手—如何去使用Vue完成项目的开发 老手—深度理解特性背后的原理 3、达到学习…

QRTCN区间预测 | Matlab实现QRTCN时间卷积神经网络分位数回归区间预测

区间预测 | Matlab实现QRTCN时间卷积神经网络分位数回归区间预测 目录 区间预测 | Matlab实现QRTCN时间卷积神经网络分位数回归区间预测预测效果基本介绍模型特性程序设计参考资料预测效果 基本介绍 Matlab实现QRTCN时间卷积神经网络分位数回归区间预测 QRTCN(Quantile Regres…

Kafka 快速入门

目录 介绍 KafKa 相关术语 ​编辑 Kafka的工作流程 生产者向kafka发送数据的流程 Kafka选择分区的模式 Kafka选择分区的模式 数据消费 kafka的文件存储机制 topic、partition和segment 存储和查找message的过程 数据写入过程 数据查找过程 注意事项 kafka管理UI …

【hot100-java】二叉树的最近公共祖先

二叉树篇 我觉得是比两个节点的深度&#xff0c;取min&#xff08;一种情况&#xff09; DFS解题。 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode(int x) { val x; }* }*/ clas…

Redis set类型 zset类型

set类型 类型介绍 集合类型也是保存多个字符串类型的元素的&#xff0c;但和列表类型不同的是&#xff0c;集合中 1&#xff09;元素之间是⽆序 的 2&#xff09;元素不允许重复 ⼀个集合中最多可以存储 个元素。Redis 除了⽀持 集合内的增删查改操作&#xff0c;同时还⽀持多…