【Flask】Flask数据库

news2024/10/24 18:30:18

【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'] = True

db = 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.name


class 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.coloradmin.cn/o/2210927.html

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

相关文章

Java体系中的泛型

1. 泛型 一般的类和方法&#xff0c;只能够使用基本类型&#xff0c;要么是自定义的类&#xff0c;如果要编写可以应用于多种数据类型的代码&#xff0c;这种刻板的限制对代码的约束就会很大&#xff0c;那么如何实现可应用于多种数据类型的代码&#xff0c;而不局限于单一一种…

第5篇:DDOS病毒----应急响应之Linux实战篇

现象描述 某服务器网络资源异常,感染该木马病毒的服务器会占用网络带宽&#xff0c;甚至影响网络业务正常应用。 系统分析 针对日志服务器病毒事件排查情况&#xff1a; 在开机启动项/etc/rc.d/rc.local发现可疑的sh.sh脚本&#xff0c;进一步跟踪sh.sh脚本,这是一个检测病毒…

C++从入门到起飞之——AVL树 全方位剖析!

&#x1f308;个人主页&#xff1a;秋风起&#xff0c;再归来~&#x1f525;系列专栏&#xff1a;C从入门到起飞 &#x1f516;克心守己&#xff0c;律己则安 目录 1. AVL的概念 2. AVL树的实现 2.1 AVL树的结构 2.2 AVL树的插⼊ >AVL树插⼊⼀个值的⼤概过程 &…

Rocky linux 修改ip地址, rocky服务器修改静态地址, rocky虚拟机修改ip

1. 更新yum yum update 2. 安装ifconfig yum install net-tools 3. 修改配置 vi /etc/NetworkManager/system-connections/ens33.nmconnection 将ipv4内容修改如下&#xff1a; # 自动改为手动 methodmanual # 网关为vm ware 查看网关地址 address你想改为的ip/24,网关 #dns不…

Qml 分组动画(二) 动画嵌套(自学笔记)

分组动画嵌套示例&#xff0c;直接看效果&#xff0c; 做一个踢足球的示例 下面两个Rectangle 制作渐变的天空和大地 下面这个Rectangle 用于放置足球图片&#xff0c; 由于足球图片直接从网上下载的 没有找到合适大小的图片 &#xff0c;所以用 一个矩形框作限制&#xff0c;…

闲谈Promise

预备知识 回调函数&#xff1a;当一个函数作为参数传入另一个函数中&#xff0c;并且它不会立刻执行&#xff0c;当满足一定条件之后&#xff0c;才会执行&#xff0c;这种函数称为回调函数。比如&#xff1a;定时器。异步任务&#xff1a;与之对应的概念是同步任务&#xff0…

【JVM】面试篇

1 什么是JVM&#xff1f; 1.1 定义 JVM 指的是Java虚拟机&#xff08; Java Virtual Machine &#xff09;。JVM 本质上是一个运行在计算机上的程序&#xff0c;他的职责是运行Java字节码文件&#xff0c;Java虚拟机上可以运行Java、Kotlin、Scala、Groovy等语言。 启动这个程…

电子电气架构---软件定义汽车的新兴生态系统

我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 屏蔽力是信息过载时代一个人的特殊竞争力&#xff0c;任何消耗你的人和事&#xff0c;多看一眼都是你的不…

【含文档】基于Springboot+Vue的校园体育器材管理系统(含源码+数据库+lw)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 系统定…

C++ : STL容器之vector剖析

STL容器之vector剖析 一、构造函数与赋值&#xff08;一&#xff09;默认构造&#xff08;二&#xff09;拷贝构造&#xff08;三&#xff09;几个相同值构造&#xff08;四&#xff09;迭代器构造&#xff08;五&#xff09;initializer_list 构造&#xff08;六&#xff09;赋…

网络编程(19)——C++使用asio协程实现并发服务器

十九、day19 上一节学习了如果通过asio协程实现一个简单的并发服务器demo&#xff08;官方案例&#xff09;&#xff0c;今天学习如何通过asio协程搭建一个比较完整的并发服务器。 主要实现了AsioIOServicePool线程池、逻辑层LogicSystem、粘包处理、接收协程、发送队列、网络…

C语言入门:打开编程世界的大门

一.C语言是什么 在我们生活中&#xff0c;我们在交流时候使用的就是语言&#xff0c;在这个世界上有许多的国家、民族&#xff0c;自然也有很多语言如&#xff1a;汉语、英语、法语等等&#xff0c;这种人与人交流使用的语言我们称为自然语言。然而计算机并不能理解我们的语言…

github下载文件的两种方式(非git形式)

1.以下面的图为例 &#xff0c;可以直接点击右上方的绿色Code按键&#xff0c;在弹出的列表中选择Download Zip选项&#xff0c;即可下载。 2.如果下载的是单独的某一个文件&#xff0c;则可以按照下图的格式点击下图所示的那个下载的图标即可。

【Linux系统编程】第三十一弹---深入理解静态库:从零开始制作与高效使用的完全指南

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】 目录 1、静态库 1.1、怎么做静态库 1.2、怎么使用静态库 1、静态库 1.1、怎么做静态库 在Linux环境下&#xff0c;通常使用GCC&am…

【2024最新】基于springboot+vue的实验室管理系统lw+ppt

作者&#xff1a;计算机搬砖家 开发技术&#xff1a;SpringBoot、php、Python、小程序、SSM、Vue、MySQL、JSP、ElementUI等&#xff0c;“文末源码”。 专栏推荐&#xff1a;SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;Java精选实战项…

PAT甲级-1034 Head of a Gang

题目 题目大意 一个犯罪团伙满足条件&#xff1a;人数 > 2&#xff1b;团伙内的总通话时长 > k。团伙首领就是该团伙中通话时长最多的。先给定一组通话&#xff0c;格式为 A B time&#xff0c;要求输出犯罪团伙的数目&#xff0c;并输出每个团伙的首领名字和该团伙的人…

一文详解数据库范式

背景 在开发中&#xff0c;我们经常需要考虑如何设计合适的表结构&#xff0c;而则往往需要考虑数据库的范式。数据库的三范式&#xff08;3NF&#xff09;是数据库设计过程中用来减少数据冗余和提高数据一致性的重要规则。它们分别是第一范式&#xff08;1NF&#xff09;、第二…

【PR小技巧】PR技术分享 一 PR关键帧小技巧介绍

在Adobe Premiere Pro (简称PR) 中&#xff0c;关键帧是用于控制视频剪辑、音频轨道、效果动画等随时间变化的重要工具。通过合理使用关键帧&#xff0c;可以实现各种复杂的动画效果和精确的时间控制。今天我们就来学习一些关于关键帧的小技巧&#xff0c;以及具体的例子来说明…

算法专题五: 位运算

目录 常见位运算总结1. 位1的个数2. 比特位计数3. 汉明距离4. 只出现一次的数字5. 只出现一次的数字Ⅲ6. 判定字符是否唯一7. 丢失的数字8. 两正数之和9. 只出现一次的数字Ⅲ10. 消失的两个数字 常见位运算总结 重点 : 1. 位1的个数 算法思路: 这道题就用到了我们总结的那个第…

全新YOLOv11美化版检测界面 涵盖超多功能 支持百种模型改进训练

文章目录 前言视频效果必要环境一、界面功能概述1. 运行方法2. 图像选择图像:表格信息:统计信息:IOU和NMS调节:目标框显示: 3. 文件夹选择文件夹:进度显示:推理结果: 4. 视频、摄像头进度显示:实时检测:帧状态回溯: 5. 替换界面中的模型5. 鼠标悬浮 二、训练改进模型运行方法假…