Flask-SQLAlchemy 数据库操作

关于Flask数据库

Flask中没有指定使用的数据库,可以自由选择不管你是使用关系型数据库,还是非关系型数据库都可以,不像django提供了orm 数据库抽象层,可以直接采用对象的方式操作数据库。但是为了开发效率,在开发Flask项目中我们一般会选择 SQLALchemy 来操作数据库,类似于Django的ORM。SQLALchemy实际上是对数据库的抽象,让开发者不直接使用sql语句做开发,而是通过Python对象来操作数据库,在舍弃一些性能开销的同时,换来的是开发效率的较大提升。

SQLAlchemy是一个关系型数据库框架,它提供了高层的ORM和底层的原生数据库的操作。为了简化配置和操作,我们使 Flask-SQLAlchemy,这个 Flask 扩展封装了 SQLAlchemy 框架。

安装 Flask-SQLAlchemy

pip install Flask-SQLAlchemy

要连接mysql数据库还需要安装flask-mysqldb

pip install flask-mysqldb

如果安装报下面错误

Command "python setup.py egg_info" failed with error code 1

请先安装执行下面这条命令:(Linux)

sudo apt-get install mysql-server libmysqld-dev

示例:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
​
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:xxxxxx@127.0.0.1/flask01'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True  # 追踪对象的修改并且发送信号
db = SQLAlchemy(app)
​
class User(db.Model):# SQLAlchemy 需要手动执行主键列,第一个参数是 字段类型,第二个参数是约束条件id = db.Column(db.Integer,primary_key=True)name = db.Column(db.String(20),unique=True)
​
if __name__ == '__main__':with app.app_context():  # 添加应用上下文# 创建所有表db.create_all()

1. 数据库连接配置

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
​
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:mysql@127.0.0.1:3306/py'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True  # 追踪对象的修改并且发送信号
db = SQLAlchemy(app)

配置键说明

配置键说明
SQLALCHEMY_DATABASE_URI设置连接数据库<br>格式:mysql://username:password@server/db
SQLALCHEMY_BINDS一个映射绑定 (bind) 键到 SQLAlchemy 连接 URIs 的字典。更多的信息请参阅 绑定多个数据库。
SQLALCHEMY_ECHO如果设置成 True,SQLAlchemy 将会记录所有 发送 标准输出(stderr)的语句,这对调试很有帮助。
SQLALCHEMY_RECORD_QUERIES可以用于显式地禁用或者启用查询记录。查询记录 在调试或者测试模式下自动启用。更多信息请参阅 get_debug_queries()。
SQLALCHEMY_NATIVE_UNICODE可以用于显式地禁用支持原生的 unicode。这是 某些数据库适配器必须的(像在 Ubuntu 某些版本上 的 PostgreSQL),当使用不合适的指定无编码的数 据库 默认值时。
SQLALCHEMY_POOL_SIZE数据库连接池的大小、默认是数据库引擎的默认值 (通常是 5)。
SQLALCHEMY_POOL_TIMEOUT指定数据库连接池的超时时间。默认是 10。
SQLALCHEMY_POOL_RECYCLE自动回收连接的秒数。这对 MySQL 是必须的,默认 情况下 MySQL 会自动移除闲置 8 小时或者以上的连 接。需要注意的是如果使用 MySQL 的话,Flask-SQLAlchemy 会自动地设置这个值为 2 小时。
SQLALCHEMY_MAX_OVERFLOW控制在连接池达到最大值后可以创建的连接数。当这 些额外的连接回收到连接池后将会被断开和抛弃。
SQLALCHEMY_TRACK_MODIFICATIONS如果设置成 True (默认情况),Flask-SQLAlchemy 将 会追踪对象的修改并且发送信号。这需要额外的内 存,如果不必要的可以禁用它。
SQLALCHEMY_COMMIT_ON_TEARDOWN每次请求结束后会自动提交数据库中的改动

数据库URI格式

数据库URI格式
MySQLmysql://username:password@hostname/database
Postgrespostgresql://username:password@hostname/database
SQLite (Unix)sqlite:////python/data/database
SQLite (Windows)sqlite:///c:/db/data/database
Oracleoracle://scott:tiger@127.0.1:1521/sidname

字段说明: username:登录数据库的用户名 password:登录数据库的密码 hostname:服务器主机 ip,可以是本地主机(localhost)也可以是远程服务器 database:表示要使用的数据库


2. 模型类定义

字段类型

类型名Python中类型说明
Integerint普通整数,一般是32位
SmallIntegerint小整数
BigIntegerint或long大整数
Floatfloat浮点数
Numericdecimal.Decimal普通整数,一般是32位
Stringstr变长字符串
Textstr变长字符串,对较长或不限长度的字符串做了优化
Unicodeunicode变长Unicode字符串
UnicodeTextunicode变长Unicode字符串,对较长或不限长度的字符串做了优化
Booleanbool布尔值
Datedatetime.date时间
Timedatetime.datetime日期和时间
LargeBinarystr二进制文件

约束条件

约束说明
primary_key主键
unique唯一约束,True不允许重复
index索引,如果为True,为这列创建索引,提高查询效率
nullable空值,如果为True,允许有空值,如果为False,不允许有空值
default默认值

关系类型

关系说明
One To Many(一对多)表示一对多的关系时,在子表类中通过 foreign key (外键)引用父表类,在父表类中通过 relationship() 方法来引用了表的类
One To One(一对一)一对一是两张表之间本质上的双向关系。只需要在一对多关系基础上的父表中使用 uselist=False 参数来表示
Many To Many(多对多)多对多关系会在两个类之间增加一个关联的表,连个关系表中使用 relationship() 方法中通过 secondary 来引用关联表,关联表通过 MetaData 对象与声明基类关联,使用ForeignKey 连接接来定位到远程的表

3. 关系模型

一对多关系
class Father(db.Model):"""创建一个父表模型类"""# 表名__tablename__ = 'father'# id主键列,整数类型,自增id = db.Column(db.Integer, primary_key=True)# name,可变长字符串类型name = db.Column(db.String(20))# 关系字段,不是数据库中真实存在的字段,而是为了方便查询添加的属性son = db.relationship('Son', backref='father')
​
class Son(db.Model):"""创建一个子表模型类"""# 表名__tablename__ = 'son'# id主键列,整数类型,自增id = db.Column(db.Integer, primary_key=True)# name,可变长字符串类型name = db.Column(db.String(20))# 外键,需要指定字段类型,以及关联那个表的那个字段father_id = db.Column(db.Integer, db.ForeignKey('father.id'))
一对一关系
class Father(db.Model):"""创建一个父类模型类"""# 表名__tablename__ = 'father'# id主键列,整数类型,自增id = db.Column(db.Integer, primary_key=True)# name,可变长字符串类型name = db.Column(db.String(20))# 关系字段,不是数据库中真实存在的字段,而是为了方便查询添加的属性son = db.relationship('Son', backref='father', uselist=False)
​
class Son(db.Model):"""创建一个子表模型类"""# 表名__tablename__ = 'son'# id主键列,整数类型,自增id = db.Column(db.Integer, primary_key=True)# name,可变长字符串类型name = db.Column(db.String(20))# 外键,需要指定字段类型,以及关联那个表的那个字段father_id = db.Column(db.Integer, db.ForeignKey('father.id'))
多对多关系
# 多对多关系中的两个表之间的一个关联表
association_table = db.Table('association', db.metadata,db.Column('author_id', db.Integer, db.ForeignKey('author.id')),db.Column('book_id', db.Integer, db.ForeignKey('book.id'))
)
​
class Author(db.Model):"""创建作者模型类"""# 指定表名,如果没有指定将默认使用模型类的名称__tablename__ = 'author'# id 类型是整数 主键列id = db.Column(db.Integer, primary_key=True)# name 类型是可变长字符串,唯一name = db.Column(db.String(20), unique=True)# 关联中间表,不是数据库中真实存在的字段,而是为了方便查询添加的属性book = db.relationship('Book', back_populates='author',secondary=association_table)
​
class Book(db.Model):"""创建书模型类"""# 指定表名,如果不指定将使用模型类名称作为表名__tablename__ = 'book'id = db.Column(db.Integer, primary_key=True)name = db.Column(db.String(20))# 关联中间表,不是数据库中真实存在的字段,而是为了方便查询添加的属性author = db.relationship("Author", secondary=association_table,back_populates="book")

4. 数据操作

创建表

if __name__ == '__main__':# 删除所有表,注意这条是危险命令,会将模型类对应数据库中的表物理删除。在实际生产环境下勿用。db.drop_all()# 创建所有表db.create_all()

添加数据

# 创建一个 father对象
f = Father(name='小头爸爸')
# 将数据添加到会话
db.session.add(f)
# 提交会话数据
db.session.commit()
​
# 创建两个Son对象,这里利用到father对象id,需要先将Father对象提交才能拿到id
s = Son(name='大头儿子', father_id=f.id)
s1 = Son(name='中头儿子', father_id=f.id)
# 同时添加多个数据,接收一个列表做参数
db.session.add_all([s, s1])
# 提交会话数据
db.session.commit()

事务管理

# 创建一个 mother
m = Father(name='围裙妈妈')
db.session.add(m)
​
# 创建了一个妈妈,但是我们这里是Father类,需要回滚会话
db.session.rollback()

删除数据

# 删除演员表中的'吴孟达'
# 将数据查询出来
actor = Cast.query.filter(Cast.name=='吴孟达').first()
# 删除对象
db.session.delete(actor)
# 提交到数据库
db.session.commit()

更新数据

# 第一种方式:查询后修改
# 先将'梁小龙'查询出来
actor = Cast.query.filter(Cast.name=='梁小龙').first()
# 将'梁小龙'的名字改成'火云邪神'
actor.name = '火云邪神'
db.session.add(actor)
db.session.commit()
​
# 第二种方式:update方式
# 将'朱茵'修改成'紫霞仙子'
Cast.query.filter(Cast.name=='朱茵').update({'name':'紫霞仙子'})
db.session.commit()

5. 数据查询

基本查询方法

方法作用
all()返回数据库中所有数据,列表形式返回
first()返回查询的第一个结果,如果未查到,返回None
first_or_404()返回查询的第一个结果,如果未查到,返回404
get()返回指定主键对应的行,如不存在,返回None
get_or_404()返回指定主键对应的行,如不存在,返回404
count()返回查询结果的数量
paginate()返回一个Paginate对象,它包含指定范围内的结果

查询过滤器

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

查询示例

# filter_by 精确匹配查询,条件只能是本表的字段
Cast.query.filter_by(name='周星驰').all()
​
# first()返回查询到的第一个对象
Cast.query.first()
​
# all()返回查询到的所有对象
Cast.query.all()
​
# filter 模糊查询
Cast.query.filter(Cast.name.startswith('周'))
Cast.query.filter(Cast.name.endswith('龙'))
Cast.query.filter(Cast.name=='周星驰').all()
​
# like 正则模糊匹配
Cast.query.filter(Cast.name.like('周%%'))

逻辑运算查询

from sqlalchemy import and_, or_, not_
​
# 查询名字为'周星驰'并且movie_id为2的演员数据
cast.query.filter(and_(cast.name=='周星驰', cast.movie_id==2)).all()
​
# 查询名字为'周星驰'或者id为2的演员数据
cast.query.filter(or_(cast.name=='周星驰', cast.movie_id==2)).all()
​
# 查询名字不为'周星驰'的演员
cast.query.filter(not_(cast.name=='周星驰')).all()

关联查询

# 查询名字为朱茵的演员,并且查出她出演的电影
# 查询出演员'朱茵'
actor = Cast.query.filter(Cast.name=='朱茵').all()
# 直接通过 relationship 中定义的 backref 属性可以直接查询出演员对应的电影
movie = actor[0].Movie
# 通过电影直接查询出所有演员
actors = movie.cast

添加repr方法

def __repr__(self):return "Father: %s" % self.name

6. 完整示例

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
​
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:mysql@192.168.20.233:3306/py'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
db = SQLAlchemy(app)
​
class Movie(db.Model):"""创建一个电影模型类"""# 表名__tablename__ = 'movie'# id主键列,整数类型,自增id = db.Column(db.Integer, primary_key=True)# name,可变长字符串类型name = db.Column(db.String(20))# 关系字段,不是数据库中真实存在的字段,而是为了方便查询添加的属性cast = db.relationship('Cast', backref='Movie')def __repr__(self):return "Movie: %s " % self.name
​
class Cast(db.Model):"""演员模型类"""# id主键列,整数类型,自增id = db.Column(db.Integer, primary_key=True)# name,可变长字符串类型name = db.Column(db.String(20))# 外键关联idmovie_id = db.Column(db.Integer, db.ForeignKey('movie.id'))def __repr__(self):return "Cast: %s " % self.name
​
if __name__ == '__main__':# 删除所有表db.drop_all()# 创建所有表db.create_all()# 创建电影数据m1 = Movie(name='大话西游')m2 = Movie(name='功夫')db.session.add_all([m1, m2])db.session.commit()# 创建演员数据cast_list = []for i in ['周星驰','朱茵','吴孟达','莫文蔚']:c = Cast(name=i, movie_id=m1.id)cast_list.append(c)for i in ['周星驰','梁小龙','元华']:c = Cast(name=i, movie_id=m2.id)cast_list.append(c)db.session.add_all(cast_list)db.session.commit()

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

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

相关文章

Camera相机人脸识别系列专题分析之十九:MTK ISP6S平台FDNode原生代码

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、问题背景 二、MTK ISP6S平台FDNodeImp.cpp 2.1:原生代码

S32K3 的图形化配置和EB配置mcal差异

32K3系列的图形化配置工具&#xff08;如S32 Design Studio, S32DS&#xff09;与EB配置工具&#xff08;基于EB tresos Studio&#xff09;在配置MCAL&#xff08;Microcontroller Abstraction Layer&#xff09;时存在关键差异&#xff0c;主要体现在工具环境、配置流程、代码…

Meta 再次重组人工智能部门

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

在nodejs中 有哪些是 “假值“和怎么写 “双重否定”

1.在 Node.js&#xff08;以及 JavaScript&#xff09;中&#xff0c;以下值在布尔上下文&#xff08;例如 if 语句、while 循环条件等&#xff09;中被视为 “假值”&#xff1a;false&#xff1a;布尔类型的 false 值&#xff0c;这是最直接的假值。if (false) {console.log(…

车载软件架构 --- 赢得汽车软件开发竞赛

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…

机器学习总复习

这段时间学习了 KNN&#xff0c;线性回归&#xff0c;逻辑回归&#xff0c;贝叶斯&#xff0c;聚类&#xff08;K-means,DBSCAN&#xff09;&#xff0c;决策树&#xff0c;集成学习&#xff08;随机森林&#xff0c;XGboost&#xff09;&#xff0c;SVM支持向量机&#xff0c;…

深入解析EventPoller:Disruptor的轮询式事件处理机制

EventPoller 是什么&#xff1f;EventPoller 是 Disruptor 框架中一种 基于轮询&#xff08;poll-based&#xff09; 的事件消费机制。它与我们更常见的 BatchEventProcessor&#xff08;基于独立的消费者线程&#xff09;形成了对比。核心区别在于&#xff1a;BatchEventProce…

K8S-Secret资源对象

目录 一、Secret概述 二、Secret 类型 kubectl 创建类型 三、Secret 使用 Opaque 类型 Secret 的使用 创建 yaml 一、Secret概述 k8s secrets用于存储和管理一些敏感数据&#xff0c;比如密码&#xff0c;token&#xff0c;密钥等敏感信息。它把 Pod 想要访问的加密数据…

lua入门以及在Redis中的应用

1.基本语法1.1变量lua的变量有&#xff1a;无效值nil&#xff0c;布尔值boolean&#xff0c;数字number、字符串string、函数function、自定义类型userdata、线程thread、表table&#xff08;key-value结构&#xff09;1.2循环数值循环for i起始值, 结束值 ,间隔值 do---option…

淘宝电商大数据采集【采集内容||采集方法|工具||合规性||应用】

淘宝电商大数据采集是指通过技术手段、工具或平台&#xff0c;系统性收集淘宝&#xff08;及旗下天猫等&#xff09;生态内的各类数据&#xff0c;用于分析市场趋势、用户行为、商品表现、竞品动态等&#xff0c;为电商运营、决策提供数据支持。以下从采集内容、工具方法、合规…

ROS2核心模块

1.创建工作空间先创建工作空间ws01_plumbing&#xff0c;终端下进入工作空间的src目录&#xff0c;执行如下命令&#xff1a;ros2 pkg create --build-type ament_cmake base_interfaces_demo2.话题通信话题通信是ROS中使用频率最高的一种通信模式&#xff0c;话题通信是基于发…

Mac 上安装并使用 frpc(FRP 内网穿透客户端)指南

一、先装好 Homebrew&#xff08;macOS 的包管理器&#xff09;打开终端&#xff08;Terminal&#xff09;&#xff0c;先装命令行开发工具 xcode-select --install弹窗点“安装”&#xff0c;等待 3~5 分钟。一键安装 Homebrew /bin/bash -c "$(curl -fsSL https://raw.g…

04_接口与包管理

第4课:接口与包管理 课程目标 深入理解Go语言接口的概念和用法 掌握接口的组合和空接口 学会使用Go Modules进行包管理 理解包的导入和导出规则 1. 接口基础 1.1 接口定义 // 基本接口定义 type Shape interface {Area() float64Perimeter()

福昕PDF编辑软件高级版下载与详细图文安装教程!!

软件下载 【软件名称】&#xff1a; 福昕PDF编辑器高级版 【软件大小】&#xff1a;668.9MBa a【系统要求】&#xff1a;awin10/win11或更高 福昕&#xff0c;软件下载&#xff08;夸克网盘需手机打开&#xff09;&#xff1a;&#xff1a;福昕丨夸克网盘-资源免费下载 软件介…

利用无事务方式插入数据库解决并发插入问题(最小主键id思路)

一、背景 由于某业务需要回退某产品数据缓存列表Asset资源&#xff0c;主任务执行后&#xff0c;通过并行执行批量子任务进行数据回退&#xff0c;子任务中会记录缓存列表Asset和缓存列表行AssetLine数据&#xff0c;并行执行过程会出现缓存列表行AssetLine重复插入问题&#…

如何制作免费的比特币冷钱包

本文主要从技术上讨论冷钱包的操作机制和原理&#xff0c;并不作为投资建议。对于国外的比特币玩家&#xff0c;或者打算长期囤币来对抗通货膨胀的&#xff0c;或者是想短期持有的&#xff0c;那么将比特币存储在哪里是一个Common的问题。一般是两类选择。第一种选择是存储在交…

新手向:Python制作简易音乐播放器

使用Python构建简易音乐播放器音乐播放器是现代数字生活中不可或缺的工具&#xff0c;从智能手机到电脑系统&#xff0c;几乎每个设备都内置了音乐播放功能。对于Python初学者来说&#xff0c;开发一个简易的音乐播放器是一个很好的实践项目&#xff0c;既能学习编程基础&#…

【StarRocks】TabletChecker逻辑

TabletChecker是StarRocks FE里的一个组件,它的主要工作是检查出所有的处于不健康状态的tablets。 注意,它的职责就是check(检查)。 至于tablet修复、均衡等调度工作不是TabletChecker的职责。 相关配置项 // 20秒执行一次check,代码里是执行runAfterCatalogReady()publi…

低空经济展 | 优翼仿真携eVTOL全动飞行模拟器亮相2025深圳eVTOL展

2025深圳eVTOL展将于2025年9月23-25日在深圳坪山燕子湖国际会展中心举行。展会以“低空经济・eVTOL・航空应急救援・商载大型无人运输机”为主题&#xff0c;以 “2天大会3天展览项目考察飞行表演颁奖盛典项目路演”的多元模式&#xff0c;打造覆盖 eVTOL全产业链的专业化合作平…

AI驱动商业革新:开源大模型与零售精准营销引领产业升级

在当今数字化浪潮中&#xff0c;AI 正以迅猛之势渗透至商业的每一处脉络&#xff0c;掀起一场影响深远的变革风暴&#xff0c;从根本上改写着商业运转的底层逻辑&#xff0c;创造出无数崭新的商业契机。基础模型领域&#xff0c;新的突破正在重塑行业格局。Meta 旗下的 LLaMA 3…