Flask Web开发:数据库

目录

在虚拟环境中安装Flask-SQLAlchemy:

一、配置

 数据库配置示例:

二、定义模型

Role 和 User 模型代码: 

(1)常用的 SQLAlchemy 列类型:​编辑

(2)常用的 SQLAlchemy 列选项:

三、关系

在数据库模型中定义关系补充如下:

常用的 SQLAlchemy 关系选项:​编辑

除了一对多关系之外:

四、数据库操作

(1)设置FLASK_APP 环境变量

 (2)虚拟环境终端中使用 flask shell 命令启动

4.1 创建表

4.2 插入行

(1)创建一些角色和用户如下:

(2)对数据库的改动通过数据库会话(也称事务)管理,由 db.session 表示。准备把对象写入数据库之前,要先将其添加到会话中:

 (3)然后我们调用 commit() 方法提交会话,这样对象才被真正写入了数据库。

(4)数据库会话(事务)可以保证数据库的一致性。

  (5)要查看data.sqlite。

4.3 修改行

4.4 删除行

4.5 查询行

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

 如果退出了当前 shell,再重新打开的。

(2)常用的 SQLAlchemy 查询过滤器:


这里我们使用 Flask-SQLAlchemy 扩展来进行数据库操作,SQLAlchemy 是一个强大的关系型数据库框架,支持多种数据库后台。SQLAlchemy 提供了高层 ORM,也提供了使用数据库原生 SQL 的低层功能。

在虚拟环境中安装Flask-SQLAlchemy

pip install flask-sqlalchemy

一、配置

在 Flask-SQLAlchemy 中,数据库使用 URL 指定,如下:

数据库引擎    URL
MySQL    mysql://username:password@hostname/database
Postgres    postgresql://username:password@hostname/database
SQLite(Linux,macOS)    sqlite:absolute/path/to/database
SQLite(Windows)    sqlite:///c:/absolute/path/to/databasehostname:数据库服务所在的主机
database:要使用的数据库名
username:数据库用户名
password:数据库密码

注意:

SQLite 数据库没有服务器,因此不用指定 hostname、username 和 password。URL 中的 database 是磁盘中的文件名。
使用的数据库URL必须保存到 Flask 配置对象的 SQLALCHEMY_DATABASE_URI 键中。
建议把 SQLALCHEMY_TRACK_MODIFICATIONS 键设为 False,以便在不需要跟踪对象变化时降低内存消耗。

 数据库配置示例:

import os
from flask_sqlalchemy import SQLAlchemy# 定义SQLite绝对路径
basedir = os.path.abspath(os.path.dirname(__file__))app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + \os.path.join(basedir, 'data.sqlite')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app) # 实例化SQLAlchemy

二、定义模型


在 ORM(对象关系映射器)中,模型一般是一个 Python 类,类中的属性对应于数据库表中的列。Flask-SQLAlchemy 实例为模型提供了一个基类以及一系列辅助类和辅助函数,可用于定义模型的结构。

如下实体 – 关系图中的 roles 表和 users 表,我们可以分别定义为 Role 和 User 模型:

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__ 定义在数据库中使用的表名,如不定义,则会使用默认的表名。
db.Column 类构造函数的第一个参数是数据库列和模型的类型,其他参数则是一些列选项,如主键(primary_key)、索引(index)、不允许重复(unique)等。
__repr()__ 方法返回一个具有可读性的字符串表示模型,不是强制要求,可方便调试和测试。


(1)常用的 SQLAlchemy 列类型:

(2)常用的 SQLAlchemy 列选项:

三、关系

关系型数据库使用关系把不同表中的行联系起来,上面那个关系图中表示的实际上是一种一对多关系,即一个角色可属于多个用户,而每个用户只能由一个角色。

在数据库模型中定义关系补充如下:

class Role(db.Model):# ...users = db.relationship('User', backref='role')class User(db.Model):# ...role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))

也就是

class Role(db.Model):__tablename__ = 'roles'id = db.Column(db.Integer, primary_key=True)name = db.Column(db.String(64), unique=True)users = db.relationship('User', backref='role')class User(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'))

         将 User 模型中的 role_id 列定义为外键,来联接这两个表。传给 db.ForeignKey() 的参数 roles.id 声明,这列的值是 roles 表中相应行的 id值。


        添加到 Role 模型中的 users 属性,代表整个关系的面向对象视角,对于一个 Role 类的实例,其 users 属性将返回与角色相关联的用户组成的列表。


         db.relationship() 的第一个参数编码整个关系的另一端是哪个模型;backref 参数向 User 模型中添加一个 role 属性,从而定义反向关系。通过 User 实例的这个role属性可以获取对应的 Role 模型的对象数情况下,db.relationship() 都能自行找到关系中的外键,但有时却无法确定哪一列是外键。

         例如,如果 User 模型中有两个或以上的列定义为 Role 模型的外键,SQLAlchemy 就不知道该使用哪一列。如果无法确定外键,就要为 db.relationship() 提供额外的参数。

常用的 SQLAlchemy 关系选项:

除了一对多关系之外:

一对一 关系可以用一对多关系表示,但调用 db.relationship() 时要把 uselist 设为 False ,把“多”变成“一”。
多对一 关系也可使用一对多表示,对调两个表即可,或者把外键和 db.relationship() 都放在“多”这一侧。
最复杂的关系类型是多对多 ,需要用到第三张表,这个表称为关联表(或联结表 )。

四、数据库操作


为了方便学习,我们先再Python shell中实际操作数据库模型,先设置 FLASK_APP 环境变量,然后再虚拟环境终端中使用 flask shell 命令启动。

(1)设置FLASK_APP 环境变量

先看要运行的.py文件是哪个目录下

根据图片可知,路径 D:\webflask\shiyan5\示例5-1\hello5-1.py, Flask 应用程序文件名为 hello5-1.py

在运行 flask shell 命令之前,请确保已经正确设置了环境变量 FLASK_APP,并且值为应用程序文件的完整路径。在 Windows 环境下,可以使用以下命令设置环境变量:

set FLASK_APP=D:\webflask\shiyan5\示例5-1\helloa1.py

 (2)虚拟环境终端中使用 flask shell 命令启动

flask shell

4.1 创建表

首先要让 Flask-SQLAlchemy 根据模型类创建数据库。 db.create_all() 函数将寻找所有 db.Model 的子类,然后再数据库中创建对应的表:

>>> from helloa1 import db
>>> db.create_all()

执行完上面命令后,在应用目录中就会产生一个 data.sqlite文件。

如果数据库表已经存在于数据库中,那么 db.create_all() 不会重新创建或者更新相应的表。使用 db.drop_all() 可以删除旧表,然后再重新创建,这样可以更新数据库,但是并不推荐,因为会丢失原有的数据。

 更新现有数据库表的粗暴方式是先删除旧表再重新创建:

>>> db.drop_all()
>>> db.create_all()

4.2 插入行

(1)创建一些角色和用户如下:

>>> from helloa1 import Role, User
>>> admin_role = Role(name='Admin')
>>> mod_role = Role(name='Moderator')
>>> user_role = Role(name='User')
>>> user_john = User(username='john', role=admin_role)
>>> user_susan = User(username='susan', role=user_role)
>>> user_david = User(username='david', role=user_role)

1.模型的构造函数接受的参数是使用关键字参数指定的模型属性初始值。
2.role 属性也可使用,虽然它不是真正的数据库列,但却是一对多关系的高级表示。
3.id 属性为主键,通常有数据库自身管理。而现在这些对象只存在于 Python 中,还未写入数据库,因此 id 并未赋值。


(2)对数据库的改动通过数据库会话(也称事务)管理,由 db.session 表示。准备把对象写入数据库之前,要先将其添加到会话中:

>>> db.session.add(admin_role) 
>>> db.session.add(mod_role) 
>>> db.session.add(user_role) 
>>> db.session.add(user_john) 
>>> db.session.add(user_susan) 
>>> db.session.add(user_david)

也可以简写成

>>> db.session.add_all([admin_role, mod_role, user_role, user_john, user_susan, user_david])

 (3)然后我们调用 commit() 方法提交会话,这样对象才被真正写入了数据库。

>>> db.session.commit()

(4)数据库会话(事务)可以保证数据库的一致性。

         提交操作使用原子方式把会话中的对象全部写入数据库。如果在写入会话的过程中发生了错误,那么整个会话都会失效。如果你始终把相关改动放在会话中提交,就能避免因部分更新导致的数据库不一致。

数据库会话也可以调用 db.session.rollback() 进行回滚,回滚后添加到数据库会话中的所有对象都将还原到它们在数据库中的状态。

  (5)要查看data.sqlite。

位于 D:\webflask\shiyan5\示例5-1\data.sqlite 路径下的 SQLite 数据库中的表,请按照以下步骤操作:

  1. 打开 SQLite 命令行工具。你可以在终端中输入以下命令:

    sqlite3 D:\webflask\shiyan5\示例5-1\data.sqlite
  2. 在 SQLite 命令行工具中,输入 .tables 命令。这将显示出当前数据库中的所有表格名称。

    .tables
  3. 如果你想查看某个特定表格中的数据,请使用 SELECT 查询语句。例如,如果你想查看名为 users 的表格中的所有数据,请输入以下命令:

    SELECT * FROM users;

    这将返回 users 表格中的所有数据。

  4. 请注意,表格名称必须以小写字母输入,否则可能会找不到表格。另外,建议在表格名称后面添加分号(;)来结束查询语句,这样可以确保命令被正确解释。

4.3 修改行

在数据库会话上调用 add() 方法也可以更新模型,如将 Admin 角色重命名未 Administrator

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

 

4.4 删除行

数据库会话可以用 delete() 方法来删除数据,如将 Moderator 角色从数据库中删除:

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

 

删除与插入和更新一样,只有提交数据库会话后才会执行。

4.5 查询行

(1)Flask-SQLAlchemy 为每个模型类都提供了 query 对象。最基本的模型查询是使用 all() 方法取回对应表中所有记录:
>>> Role.query.all()
[<Role 'Administrator'>, <Role 'User'>]
>>> 
>>> User.query.all()
[<User 'john'>, <User 'susan'>, <User 'david'>]

使用过滤器可以配置 query 对象来进行更精准的数据库查询,如查找角色为 “User” 的所有用户

>>> User.query.filter_by(role=user_role).all()
[<User 'susan'>, <User 'david'>]

 若想查看 SQLAlchemy 为查询生成的原生SQL语句,可以将 query 对象转换为字符串:

>>> str(User.query.filter_by(role=user_role))
'SELECT users.id AS users_id, users.username AS users_username, users.role_id AS users_role_id \nFROM users \nWHERE ? = users.role_id'

 如果退出了当前 shell,再重新打开的。

前面例子创建的对象就不会以 Python 对象的方式存在,只能从数据库表中进行读取,重新创建Python对象。如下例发起一个查询,加载名为“User” 的用户角色:

user_role = Role.query.filter_by(name='User').first()
  • first() 方法只返回第一个结果,如果没有结果的化,返回None。
  • all() 方法以列表的形式返回查询到的所有结果。
(2)常用的 SQLAlchemy 查询过滤器:

(3)常用的 SQLAlchemy 查询执行方法:

 (4)关系与查询的处理方式类似,下面的例子首先查询角色为 User 的用户有哪些,然后又查询了用户susan的角色是什么,分别从关系的两端查询角色和用户之间的一对多关系。

>>> users = user_role.users
>>> users
[<User 'susan'>, <User 'david'>]
>>> users[0].role
<Role 'User'>

 可以发现这里再执行 user_role.users时,隐式的调用了 all()方法,此时 query 对象被隐藏了,这样就无法再使用过滤器进行更精准的查询(如将结果按字母顺序排序)。

要想解决这个问题,我们需要在 Role 类的 db.relationship() 方法中加入 lazy='dynamic' 参数的设置,从而禁止自动执行查询。

示例5-4:helloa1.py:动态数据库关系

class Role(db.Model):# ...users = db.relationship('User', backref='role', lazy='dynamic')# ...

原来的

 加了之后

 这样配置关系之后,user_role.users 将返回一个尚未执行的查询,因此可以在其上添加过滤器:

>>> user_role.users.order_by(User.username).all()
[<User 'david'>, <User 'susan'>]
>>> user_role.users.count()
2

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

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

相关文章

手撕单链表(C语言)

目录 1.单链表的物理结构 2.头文件的实现 3.SList.c文件的实现 3.1尾插、创建节点 3.2打印 3.3头插 3.4尾删 3.5头删 3.6查找 3.7指定位置之前插入数据 3.8指定位置之后插入数据 3.9删除指定位置节点 3.10删除pos之后的节点 3.11销毁链表 4 所有的代码 1.单链表的物理结构 众所…

第十篇 基于JSP 技术的网上购书系统——管理员后台管理主界面、订单管理、产品管理功能实现(网上商城、仿淘宝、当当、亚马逊)

目录 1.管理员后台管理——主界面 1.1功能说明 1.2界面设计 1.3处理流程 2.订单管理 2.1功能说明 2.2界面设计 2.3处理流程 2.4数据来源和算法 2.4.1数据来源 2.4.2查询条件 2.4.3表间关系 2.4.4相关sql实例 3.产品管理 3.1功能说明 3.2界面设计 3.3处理流程…

Mybatis系列之 parameterMap 弃用了

我 | 在这里 &#x1f575;️ 读书 | 长沙 ⭐软件工程 ⭐ 本科 &#x1f3e0; 工作 | 广州 ⭐ Java 全栈开发&#xff08;软件工程师&#xff09; &#x1f383; 爱好 | 研究技术、旅游、阅读、运动、喜欢流行歌曲 &#x1f3f7;️ 标签 | 男 自律狂人 目标明确 责任心强 ✈️公…

【视觉SLAM十四讲学习笔记】第三讲——旋转矩阵

专栏系列文章如下&#xff1a; 【视觉SLAM十四讲学习笔记】第一讲——SLAM介绍 【视觉SLAM十四讲学习笔记】第二讲——初识SLAM 本章将介绍视觉SLAM的基本问题之一&#xff1a;如何描述刚体在三维空间中的运动&#xff1f; 旋转矩阵 点、向量和坐标系 三维空间由3个轴组成&…

担忧CentOS停服?KeyarchOS系统来支撑

担忧CentOS停服&#xff1f;KeyarchOS系统来支撑 近年发生的“微软黑屏门”、“微软操作系统停更”等安全事件&#xff0c;敲响了我国 IT 产业的警钟&#xff0c;建立由我国主导的 IT 产业生态尤为迫切。对此&#xff0c;我国信息技术应用创新行业乘势而起&#xff0c;旨在通过…

使用大语言模型 LLM 做文本分析

本文主要分享 传统聚类算法 LLM与嵌入算法 嵌入算法聚类 LLM的其他用法 聚类是一种无监督机器学习技术&#xff0c;旨在根据相似的数据点的特征将其分组在一起。使用聚类成簇&#xff0c;有助于解决各种问题&#xff0c;例如客户细分、异常检测和文本分类等。尽管传统的聚…

vue3插槽的使用

什么是插槽 Vue 3 插槽&#xff08;Slots&#xff09;是一个强大的工具&#xff0c;用于在组件之间传递内容和逻辑。通过使用插槽&#xff0c;我们可以将子组件中的内容插入到父组件中的特定位置。本篇文章将总结 Vue 3 插槽的基本用法、特点以及使用场景。 基本用法 插槽分为…

DSCNet:基于拓扑几何约束的动态蛇形卷积管状结构分割

文章目录 摘要1、简介2、相关研究2.1、基于网络设计的方法2.2、基于特征融合的方法2.3、基于损失函数的方法 3、方法3.1、动态蛇形卷积&#xff08;Dynamic Snake Convolution&#xff09;3.2、多视图特征融合策略3.3、拓扑连续性约束损失 4、实验配置4.1、数据集4.2、评估指标…

Redis篇---第十一篇

系列文章目录 文章目录 系列文章目录前言一、说说Redis持久化机制二、缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级等问题三、热点数据和冷数据是什么前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章…

harmonyOS鸿蒙开发工具下载安装以及使用流程

注册账号 进入鸿蒙官方网站&#xff1a;https://www.harmonyos.com/ 推荐使用手机号注册 进行实名认证 发布工具 华为集成开发环境IDE DevEco Device Tool下载 | HarmonyOS设备开发 下载开发工具 HUAWEI DevEco Studio和SDK下载和升级 | HarmonyOS开发者 安装 无脑下一步选…

X2Keyarch迁移工具实战 | 将CentOS高效迁移至浪潮云峦操作系统KeyarchOS

X2Keyarch迁移工具实战 | 将CentOS高效迁移至浪潮云峦操作系统KeyarchOS 1. 搭建仿真线上业务环境2. 安装KeyarchOS操作系统和X2Keyarch迁移工具3. 将CentOS系统业务迁移至KeyarchOS系统 浪潮信息云峦操作系统KeyarchOS基于Linux Kernel、OpenAnolis等开源技术自主研发的一款服…

【智能家居项目】FreeRTOS版本——将裸机程序改造成FreeRTOS程序 | DHT11温湿度传感器

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《智能家居项目》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 如上图所示是裸机版本的智能家居项目总体框架结构&#xff0c;这篇文章开始&#xff0c;本喵要…

基于GB28181搭建流媒体服务器--1.概念解析

什么是GB28181 GB28181(国标28181)&#xff0c;全称为《中华人民共和国公共安全视频监控联网系统技术要求》&#xff0c;是中国国家标准委员会发布的一个针对公共安全视频监控领域的标准框架。该标准指导了视频监控设备之间的联网互通&#xff0c;统一管理和控制&#xff0c;并…

git拉取普通idea Java项目module没有build的问题

在不断完成一个项目的时候&#xff0c;会有不断新加的module&#xff0c;我们用git拉取时会发生没有识别新module的情况。 解决方法是右键项目名称&#xff0c;然后点击Open Module Settings 接下来&#xff0c;点击Module&#xff0c;加号&#xff0c;新建Module的名字就是在g…

【数据结构】【版本2.0】【树形深渊】——二叉树入侵

目录 引言 一、树的概念与结构 1.1 树的概念 1.2 树的相关概念 1.3 树的表示 1.4 树在实际中的运用 二、二叉树的概念与结构 2.1 二叉树的概念 2.2 特殊二叉树 满二叉树 完全二叉树 2.3 现实中的二叉树 2.4 二叉树的性质 2.5 二叉树的存储结构 顺序存储 链式…

深度学习到智能小车(1)深度学习框架

0.前提 最近新开了一门叫机器学习的课程&#xff0c;老师一直在跟我们讲一些有关这方面的知识&#xff0c;告诉我们一定要学好数学&#xff0c;因为数学是算法的基础。我手上的donkeycar刚好也涉及到Keras深度神经网络&#xff0c;所以出于好奇我去图书馆借回了一本叫《Keras深…

python urllib open 头部信息错误

header 有些字符在 lighttpd server 中无法正常解析,需要转换 quteo 可以转换 就跨平台而言,Rust 和 python 一样优秀,看了在stm32 上使用 Rust 进行编程,从一定程度上,而言&#xff0c;稳定和安全性要比C 开发的好的多,说出来可能不信&#xff0c;在单片机上是可以对空指针进行…

【MySQL】聚合函数、group by、update、delete

聚合函数、group by、update、delete 前言正式开始update将孙悟空同学的数学成绩变更为 80 分将曹孟德同学的数学成绩变更为 60 分&#xff0c;语文成绩变更为 70 分将总成绩倒数前三的 3 位同学的数学成绩加上 30 分将所有同学的语文成绩更新为原来的 2 倍 delete删除孙悟空同…

【C++上层应用】1. 异常处理

文章目录 【 1. C的标准异常 】【 2. 异常转移处理 】2.1 throw 抛出异常2.2 try 捕获异常2.3 catch 捕获异常2.4 实例 【 3. 定义新的异常 】 异常是程序在执行期间产生的问题&#xff0c;比如编译报错、链接错误等。 【 1. C的标准异常 】 C 提供了一系列标准的异常&#xf…

[Spring Cloud] Nacos 实战 + Aws云服务器

文章目录 前言一、拥有一台Aws Linux服务器1.1、选择Ubuntu版本Linux系统1.2、创建新密钥对1.3、网络设置1.4、配置成功&#xff0c;启动实例1.5、回到实例区域1.6、进入具体的实例1.7、设置安全组 二、在Mac上连接Aws云服务&#xff0c;并安装配置JDK112.1、解决离奇的错误2.2…