我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Flask使用SQLAlchemy实现持久化数据

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Flask使用SQLAlchemy实现持久化数据

项目引入flask-sqlalchemy

首先,安装flask-sqlalchemy扩展:


$pip install flask-sqlalchemy

然后,在项目中导入SQLAlchemy类,并实例化应用程序使用的数据库(以mysql为例):


from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://account:password@hostname/database'
db = SQLAlchemy(app)

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

ORM简介及模型定义

在Python中,可以使用数据库相应的包直接操作数据库,如PyMySQL操作MySQL数据库,还有一些数据库抽象层代码包供选择,如这里要讨论的SQLAlchemy。该抽象包直接处理高等级的Python对象,而不用处理如表这样的数据库实体。
抽象层,就是所谓的对象关系映射(ORM),其最大的优势就是:能在用户不知觉的情况下把高层的面向对象操作转换成低层的数据库指令,极大简化代码编写。SQLAlchemy就是已与Flask很好集成的更高层抽象例子,其还支持多种关系型数据库引擎。

基于SQLAlchemy的模型定义:


class Roles(db.Model):
    __tablename__ = 'roles'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True)
    users = db.relationship('Users', backref='role')

class Users(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(64), unique=True, index=True)
    role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))

__tablename__定义在数据库中使用的表名;

db.Column类构造函数的第1个参数是数据库表列(也是模型属性)的类型,其余的参数指定属性(数据库表列)的配置选项。

2.1 常用的SQLAlchemy列类型

类型名 Python类型 说明
Integer int 普通整数,一般32位
SmallInteger int 取值范围小的整数,一般16位
BigInteger int或long 不限制精度的整数
Float float 浮点数
String str 变长字符串
Boolean bool 布尔值
Date datetime.date 日期
Time datetime.time 时间
DateTime datetime.datetime 日期和时间
Text str 变长字符串,对较长或不限长度的字符串做了优化
Numeric decimal.Decimal 定点小数

2.2 常用的SQLAlchemy列选项

选项名 说明
primary_key 如果设为True,这列就是表的主键
unique 如果设为True,这列不允许重复值
index 如果设为True,为该列创建索引,提升查询效率
nullable 如果设为True,这列允许null值,如果设为false,不允许为空
default 为这列定义默认值

表关系类型及编码实现

关系型数据库使用关系把不同表中的行联系起来。以上述模型定义代码为例,假设角色对用户是一对多的关系(即1个角色可属于多个用户,而每个用户只能有1个角色)。

一对多关系(多对一关系)

在“多”的一方,使用外键定义关系
如在Users模型中,定义role_id列为外键,给db.Column构造函数传递db.ForeignKey()参数,并将roles.id作为db.ForeignKey()的参数,其表明role_id列的值是roles表中行的id值。
在“一”的一方,基于面向对象的视角创建代表实例(记录或行)的属性,如上述的users = db.relationship(‘Users', backref=‘role')
db.relationship()的第1个参数表明这个关系的另一端是哪个模型,backref参数向Users模型添加一个role属性,从而定义反向关系。通过这一属性(role)可以替代role_id访问Roles模型,此时将获取的是模型对象,而不是外键的值。
如何理解上述这段话,可以从下面2句代码加深:


 users = inst_role.users
 user_role = user.role

通过第1句代码,可以直接获得特定角色实例(inst_role)相对应的所有users对象,且是以列表形式返回。
通过第2句代码,可以通过user实例直接获得该user所对应的role对象(1行记录,而不是Users模式定义的role_id字段值)。

一对一关系

要定义一对一的关系,只需基于一对多的模型定义基础上,给db.relationship()函数多传一个关键字表示关系选项:
users = db.relationship(‘Users', backref=‘role', userlist=False)
一对多与一对一在编码时,有个点需特别注意:当通过“一”的实例(db.relationship定义方)获取多的一方的对象时:

  • 一对多:users = inst_role.users返回的是对象列表
  • 一对一:users = inst_role.users返回的就是对象,而非列表

多对多关系

Pending…

数据库基本操作

在Flask-SQLAlchemy中,对数据库所做的改动均是通过数据库“会话”进行管理的,会话用db.session表示。如需用db.session.commit()提交对记录的修改,始终把数据库相关改动放在会话中提交,可避免因部分更新异常导致数据库中数据的不一致性。

插入


    admin_role = Roles(name='Admin')
    mod_role = Roles(name='Moderator')
    john = Users(username='liyu', role=admin_role)
    david = Users(username='liji', role=admin_role)
    db.session.add(admin_role)
    db.session.add(mod_role)
    db.session.add(john)
    db.session.add(david)
    db.session.commit()

前4行代码,实例化2种角色及2个用户对象(映射至数据库即是给记录的字段赋值)
5~7行代码就是将新增角色及用户操作放在了1个session中,最后再统一提交(commit),可防止因其中某条语句异常而更新部分从而导致数据的不一致性。该操作就是将多个原子操作组成一个事务,如果某条更新失败就会导致整个会话失效。
5~7行还可简写成: db.session.add([admin_role, mod_role, john, david])

更新

在Flask-SQLAlchemy中,一条记录表示为一个对象;记录的字段表示为对象的属性,因此要更新字段值,实际上就是对对象的属性赋值:


admin_role.name = 'Administrator'
db.session.add(admin_role)
db.session.commit()

查询

查询表中所有记录:模式.query.all()


eg. Roles.query.all()

使用过滤器进行更精确查询

过滤器 说明
filter 把过滤器添加到原查询上
filter_by 把等值过滤器添加到原查询上
limit 使用指定的值限制原查询返回的结果数量
offset 偏移原查询返回的结果
order_by 根据指定条件对原查询结果进行排序
group_by 根据指定条件对原查询结果进行分组

2.1 filter与filter_by区别

2.1.1 语法区别

filter需要用“类名.属性名”且需用==比较,而filter_by直接用属性名,比较用=


users = Users.query.filter(Users.id == 1).all()
users =  Users.query.filter_by(id = 1).all()

2.1.2 组合查询

filter不支持组合查询,只能连续用filter来实现,而filter_by支持组合查询(下面2条语句效果一样)


users = Users.query.filter(Users.id == 1).filter(Users.username == 'xxx').all()
users =  Users.query.filter_by(id = 1, username='xxx').all()
# filter_by也支持连续使用

注:如果要查看SQLAlchemy为查询生成的原生SQL查询语句,只需把query对象转换成字符串: str(Users.query.filter_by(role=admin_role))

删除

执行查询

在查询上应用指定的过滤器后,通过调用all()触发执行查询,常见的触发执行方法有: 

方法 说明
all() 查询所有结果
first() 返回查询的第1个结果,没有返回None
get() 返回指定主键对应的行,没有返回None
count() 返回查询结果的数量
first_or_404() 返回查询的第1个结果,如果没有结果,则终止请求,返回404错误响应
get_or_404() 返回指定主键对应的行,如果没找到指定的主键,则终止请求,返回404错误响应
paginate() 返回一个paginate对象

4.1 一对多

4.1.1 从“一”获取对应的所有多端对象


users = inst_role.users //直接通过角色对象的users属性获取所有属于该角色的用户对象
role = inst_user.role  //直接通过用户实例的role属性获取该用户所属的角色对象,注意这里获取的是角色对象,而不仅是角色ID

注:inst_role.users获取对象时,隐含了调用all()方法触发执行,但如果像加一些过滤器(如排序),则需要在db.relationship中添加lazy='dynamic'关键字参数。然后即可引入过滤器:inst_role.users.order_by(Users.username)

4.2 多对多

Pending…

在Flask-SQLAlchemy中,删除数据库记录,可映射至删除代表该记录的对象:


db.session.delete(mod_role)
db.session.commit()

参考资料

到此这篇关于Flask使用SQLAlchemy实现持久化数据的文章就介绍到这了,更多相关Flask SQLAlchemy持久化数据内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Flask使用SQLAlchemy实现持久化数据

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Flask如何使用SQLAlchemy实现持久化数据

这篇文章主要介绍“Flask如何使用SQLAlchemy实现持久化数据”,在日常操作中,相信很多人在Flask如何使用SQLAlchemy实现持久化数据问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Flask
2023-06-20

如何使用Redis实现数据持久化

如何使用Redis实现数据持久化引言Redis是一种快速、高效的内存数据库,但默认情况下它的数据是存储在内存中的。这就意味着一旦服务器断电或重启,Redis中的数据将会丢失。为了解决这个问题,Redis提供了一些机制来实现数据的持久化。本文
如何使用Redis实现数据持久化
2023-11-07

flask-SQLALchemy连接数据库如何实现

本文小编为大家详细介绍“flask-SQLALchemy连接数据库如何实现”,内容详细,步骤清晰,细节处理妥当,希望这篇“flask-SQLALchemy连接数据库如何实现”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知
2023-07-02

mysql怎么实现数据持久化

MySQL可以通过以下几种方式来实现数据持久化:使用磁盘存储:MySQL将数据存储在硬盘上,包括数据文件、日志文件等。这样即使服务器重启,数据也可以从硬盘上读取并恢复。使用数据库备份和恢复工具:MySQL提供了多种备份和恢复工具,如mysq
2023-10-21

mongodb数据持久化怎么实现

在MongoDB中,数据持久化是通过将数据写入硬盘来实现的。MongoDB会在后台自动将数据写入到磁盘中,以确保数据的持久性。MongoDB使用了一种称为WiredTiger的存储引擎,默认将数据持久化到磁盘。WiredTiger使用了一
2023-10-21

Vuex数据持久化怎么实现

小编给大家分享一下Vuex数据持久化怎么实现,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!什么是vuexvuex :是一个专为vue.js开发的状态管理器,采用集
2023-06-15

Redis怎么实现数据持久化

Redis 有两种数据持久化的方式:RDB持久化和AOF持久化。RDB持久化:RDB持久化是通过定期将内存中的数据快照写入磁盘来实现数据持久化的方式。可以通过配置文件中的save选项来设置保存快照的条件,比如save 900 1表示在90
Redis怎么实现数据持久化
2024-05-07

android数据持久化怎么实现

在Android中,有多种方式可以实现数据持久化,下面列举了几种常见的方法:1. Shared Preferences(共享首选项):用于存储简单的键值对数据,比如应用的设置项等。可以使用SharedPreferences类进行操作。2.
2023-10-21

使用PHP怎么实现数据库连接持久化

本篇文章给大家分享的是有关使用PHP怎么实现数据库连接持久化,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。PHP中的数据库连接持久化数据库的优化是我们做web开发的重中之重,甚
2023-06-15

Pinia简单使用及数据持久化怎么实现

这篇文章主要讲解了“Pinia简单使用及数据持久化怎么实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Pinia简单使用及数据持久化怎么实现”吧!基本介绍Pinia 是 Vue.js 的轻
2023-06-30

mysql表数据持久化怎么实现

在MySQL中,数据持久化是通过将数据存储在磁盘上的表中来实现的。以下是一些实现数据持久化的方法:创建表:首先需要创建一个表来存储数据。可以使用MySQL的CREATE TABLE语句来创建一个新的表,指定表的名称和列的定义。插入数据:使用
2023-10-26

Couchbase中怎么实现数据持久化

在Couchbase中,数据持久化可以通过以下几种方式实现:使用持久化存储引擎:Couchbase支持使用不同的持久化存储引擎来保证数据的持久化,包括Couchbase自带的Magma存储引擎、ForestDB存储引擎以及可选的第三方存储引
Couchbase中怎么实现数据持久化
2024-03-08

如何在Flask中使用SQLAlchemy连接数据库

这篇文章将为大家详细讲解有关如何在Flask中使用SQLAlchemy连接数据库,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。1、连接mysql在 Flask-SQLAlchemy 中,数据
2023-06-14

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录