flask-sqlalchemy库

彩笔激流勇退。

1. 简介

ORM,对象关系映射。简单来说,ORM将数据库中的表与面向对象中的类建立了一种对应关系。这样,我们要操作数据库,表,记录就可以直接通过操作类或者类实例来完成。

SQLAlchemy 是目前python中最垃圾的 ORM框架, 功能全面, 使用复杂。

Flask-SQLAlchemy 是一个为 Flask 应用增加 SQLAlchemy 支持的扩展,把原本pymysql几句话就能搞定的事情整成抽象的,继承的,封装的,多态的更适合高级程序员体质的负离子保温杯。

抛开兼容性不谈,Flask-SQLAlchemy无疑是磨练程序员改bug的磨刀石,是检验程序员记忆能力的试金石,是凝结了人类精华的草酸钙结石。

常用字段类型

类型名python接收类型mysql生成类型说明
Integerintint整型
Floatfloatfloat浮点型
Numeric(5,2)decimal.Decimaldecimal(5,2)
Booleanbooltinyint整型,只占1个字节
Textstrtext文本类型,最大64KB
LongTextstrlongtext文本类型,最大4GB
Stringstrvarchar变长字符串,必须限定长度
Datedatetime.datedate日期
DateTimedatetime.datetimedatetime日期和时间
Timedatetime.timetime时间
TIMESTAMPdatetime.datetimeTIMESTAMP时间戳,可以用text(‘now()’)赋值

常用的字段选项

选项名说明
primary_keyTrue,则该字段为表的主键,默认自增
uniqueTrue,则这列设置唯一
nullableFalse,则这列设置非空
default为这列设置默认值,不作用在数据库
server_default值必须是字符串格式,作用在数据库
indexTrue,则为这列创建索引,提高查询效率

如果没有给对应字段的类属性设置default参数, 且添加数据时也没有给该字段赋值, 则sqlalchemy会给该字段设置默认值 None。

常见命令

db.create_all() #创建所有表
db.drop_all() #删除所有表
2. 创建表

pip install pymysql

pip install flask-sqlalchemy

数据库URL(连接地址)格式: 协议名://用户名:密码@数据库IP:端口号/数据库名

main.py

​ 在下面代码中,我们使用了 with app.app_context(): 语句来确保当前应用实例的操作db.create_all() 是在flask应用上下文中被调用的。

from app import *
from models import User@app.route('/',methods=['GET','POST'])
def login():print(db)return 'hello world'if __name__ == '__main__':with app.app_context():db.create_all()#创建表app.run(host='0.0.0.0',port=9901,debug=1)

modules.py

表名默认为类名小写, 可以通过 __tablename__类属性 进行修改

from app import dbclass User(db.Model):# User表__tablename__ = 't_user'id= db.Column(db.Integer,primary_key=True) # 必须要有主键存在name=db.Column(db.String(20),nullable=True)# 可空age=db.Column(db.SmallInteger)gender=db.Column(db.Boolean)birthday=db.Column(db.Date)

对应MySQL语句

CREATE TABLE `t_user` (`id` int NOT NULL AUTO_INCREMENT,`name` varchar(20) COLLATE utf8mb4_general_ci DEFAULT NULL,`age` smallint DEFAULT NULL,`gender` tinyint(1) DEFAULT NULL,`birthday` date DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

app.py

from flask import Flask,url_for,request,render_template,make_response,redirect,jsonify
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__) # 用本脚本名实例化Flask对象
# 设置数据库连接地址
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:123456@127.0.0.1:3306/test1'# 是否追踪数据库修改(开启后会触发一些钩子函数)  一般不开启, 会影响性能
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False# 是否显示底层执行的SQL语句
app.config['SQLALCHEMY_ECHO'] = True# 初始化组件对象, 直接关联Flask应用
db = SQLAlchemy(app)
3. 数据表简单查询

在这里插入图片描述

user=User.query

说明
user.filter_by(id=1)只能等值查询,使用=
user.filter(User.id==1)条件查询,用==
use.filter 参数与运算符说明
and_(User.id==1,User.age==99)
or_(User.id==1,User.age==99)
~(User.id==1)
!= None>>=
User.name.like('%a%')模糊查询
User.id.in_((1,2,5))范围查询
User.id.between(1,3)[1,3]
if __name__ == '__main__':with app.app_context():db.create_all()user=User.queryprint(user)#显示sql语句, 返回Query对象print(user.all())#[<User 1>, <User 2>, <User 3>],每个元素都是models.User类型print(user.count()) #返回query中的Model对象数量print(user.filter_by(age=30,id=1)) #显示SQL语句, 返回Query对象,内部条件为交集
4. 映射查询 db.session.query

映射查询在SQLAlchemy中,可以通过session对象的query方法完成。

注意关键字书写顺序

db.session.query().filter().group_by().having().order_by().paginate().all()
if __name__ == '__main__':with app.app_context():db.create_all()query=db.session.query(User) #<class 'flask_sqlalchemy.query.Query'>print(query.filter(User.id>1).all())# [<User 2>, <User 3>]query2=db.session.query(User.id,User.name)print(query2.filter(User.age==99).all())# [(2, 'tom')]app.run(host='0.0.0.0',port=9901,debug=1)
5. 排序 order_by

from sqlalchemy import desc

if __name__ == '__main__':with app.app_context():db.create_all()query = db.session.query(User.id, User.name,User.age)print(query.order_by(User.age).all())  # 默认升序排序,asc()print(query.order_by(desc(User.age)).all())  # 降序排序print(query.order_by(User.age,User.id).all())  # 先排age,后排idapp.run(host='0.0.0.0', port=9901, debug=1)# 看起来是一个阻塞函数
6. 聚合函数

数据库先添加一个age为30的记录。

from sqlalchemy import func

聚合函数说明
count()记录数量
sum()加和总值
avg()平均值
max()最大值
min()最小值
if __name__ == '__main__':with app.app_context():db.create_all()query = db.session.query(func.max(User.age),func.avg(User.age))#相当于 SELECT max(age) , avg(age) FROM t_userprint(query.all())  # [(99, Decimal('51.0000'))]app.run(host='0.0.0.0', port=9901, debug=1)
7. 分组查询 group_by
if __name__ == '__main__':with app.app_context():db.create_all()query = db.session.query(func.count(User.id))print(query.group_by(User.age).all())  # [(2,), (1,), (1,)]app.run(host='0.0.0.0', port=9901, debug=1)
8. 增删改

flask开了debug模式,删除数据会导致main函数重新执行,给爷整笑了。

if __name__ == '__main__':with app.app_context():db.create_all()#更新u = db.session.query(User.id==1)# 查询主键为1的记录u.name="Jack"#db.session.rollback() 事务回滚,默认遇到错误自动回滚db.session.commit()# 事务提交#删除u2=db.session.query(User).filter(User.id==6).all() # User 模型的实例if len(u2)!=0:db.session.delete(u2[0])db.session.commit()  # 事务提交#增加u3=User(id=7,name="lihua",age=35,gender=1,birthday='2077-1-1')db.session.add(u3)#db.session.add_all([u1,u2,u3]) 一次添加多个db.session.commit()app.run(host='0.0.0.0', port=9901, debug=0)# debug=1时,上面的delete操作会执行多次# 大概是是检测到了文件变化重启了一次main函数???
9. 分页查询 paginate

分页查询不老老实实用limit,非要整个paginate装什么高大上。

if __name__ == '__main__':with app.app_context():db.create_all()pg=db.session.query(User).paginate(page=2,per_page=2)# QueryPagination objectprint(pg.items)#[<User 3>, <User 4>],当前页数据print(pg.pages) #3 ,一共三页for i in pg.iter_pages(): #迭代Pagination.iter_pages对象print(i)#1 2 3app.run(host='0.0.0.0', port=9901, debug=0)
10. 原生sql支持
if __name__ == '__main__':with app.app_context():db.create_all()statement=text('select * from t_user where id> :id').params(id=1)query=db.session.query(User).from_statement(statement)print(query.all())# [<User 2>, <User 3>, <User 4>, <User 7>]#最傻逼的地方来了,新版本下面语句不支持# statement2 = text('select max(id) as mmid,max(age) as mage from t_user where id> :id').params(id=2)# query2 = db.session.query('mmid','mage').from_statement(statement2)# sqlalchemy.exc.ArgumentError# 感觉不如直接pymysqlsql=text('select max(id) as mmid,max(age) as mage from t_user where id> :id')result=db.session.execute(sql,{'id':2})# CursorResult object#print(result.fetchall())# [(7, 45)] 如果这里获取了,下面就获取不了,有点类似游标后移导致没数据读for i in result:print(i)# (7, 45)app.run(host='0.0.0.0', port=9901, debug=0)

参考

flask框架与mysql开发入门到实践 白菜爱科技

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

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

相关文章

3.DOM-事件进阶(事件对象、事件委托)

环境对象this 环境对象本质上是一个关键字 this this所在的代码区域不同&#xff0c;代表的含义不同 全局作用域中的this 全局作用域中this代表window对象 局部作用域中的this 在局部作用域中(函数中)this代表window对象 原因是函数调用的时候简写了&#xff0c;函数完整写…

开发指南002-前后端信息交互规范-概述

前后端之间采用restful接口&#xff0c;服务和服务之间使用feign。信息交互遵循如下平台规范&#xff1a; 前端&#xff1a; 建立api目录&#xff0c;按照业务区分建立不同的.js文件&#xff0c;封装对后台的调用操作。其中qlm*.js为平台预制的接口文件&#xff0c;以qlm_user.…

MySQL--explain执行计划详解

什么是执行计划&#xff1f; SQL的执行计划&#xff0c;通俗来说就是SQL的执行情况&#xff0c;一条SQL语句扫描哪些表&#xff0c;那个子查询先执行&#xff0c;是否用到了索引等等&#xff0c;只有当我们知道了这些情况之后才知道&#xff0c;才可以更好的去优化SQL&#xf…

java 数据结构二叉树

目录 树 树的概念 树的表示形式 二叉树 两种特殊的二叉树 二叉树的性质 二叉树的存储 二叉树的基本操作 二叉树的遍历 二叉树的基本操作 二叉树oj题 树 树是一种 非线性 的数据结构&#xff0c;它是由 n &#xff08; n>0 &#xff09;个有限结点组成一个具有层次…

伪分布Hadoop的安装与部署

1.实训目标 &#xff08;1&#xff09;熟悉掌握使用在Linux下安装JDK。 &#xff08;2&#xff09;熟悉掌握使用在Linux下安装Hadoop。 &#xff08;3&#xff09;熟悉掌握使用配置SSH免密登录。 2.实训环境与软件 环境 版本 说明 Windows 10系统 64位 操作电脑配置 …

前端vite+vue3——可视化页面性能耗时指标(fmp、fp)

文章目录 ⭐前言&#x1f496;vue3系列文章 ⭐可视化fmp、fp指标&#x1f496; MutationObserver 计算 dom的变化&#x1f496; 使用条形图展示 fmp、fp时间 ⭐项目代码⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本文分享关于 前端vitevue3——可视化页面性能耗时…

图像处理与图像分析—图像的读入(C语言)

学习将会依据教材图像处理与图像分析基础&#xff08;C/C&#xff09;版内容展开 什么是数字图像处理 一副图像可以定义为一个二维函数 f(x&#xff0c;y) &#xff0c;其中 x 和 y 是空间&#xff08;平面&#xff09;坐标&#xff0c;任意一对空间坐标 (x,y) 处的幅度值 &am…

微信私信短剧机器人源码

本源码仅提供参考&#xff0c;有能力的继续开发 接口为api调用 云端同步 https://ys.110t.cn/api/ajax.php?actyingshilist 影视搜索 https://ys.110t.cn/api/ajax.php?actsearch&name剧名 每日更新 https://ys.110t.cn/api/ajax.php?actDaily 反馈接口 https://ys.11…

R语言复现:中国Charls数据库一篇现况调查论文的缺失数据填补方法

编者 在临床研究中&#xff0c;数据缺失是不可避免的&#xff0c;甚至没有缺失&#xff0c;数据的真实性都会受到质疑。 那我们该如何应对缺失的数据&#xff1f;放着不管&#xff1f;还是重新开始?不妨试着对缺失值进行填补&#xff0c;简单又高效。毕竟对于统计师来说&#…

NUC980开发板CAN开发笔记

一、内核开启CAN CAN 设置 NUC980 系列带有2个CAN(Controller Area Network), 可以分别独立设置。 请按以下的说明来使能CAN功能. 每个CAN可以单独的开关. CAN0有多组管脚可以选择, 需要一并设置。 使用者也可以设置CAN的唤醒功能。步骤如下&#xff1a; 进入 NUC980-linux-4.…

使用Tokeniser估算GPT和LLM服务的查询成本

将LLM集成到项目所花费的成本主要是我们通过API获取LLM返回结果的成本&#xff0c;而这些成本通常是根据处理的令牌数量计算的。我们如何预估我们的令牌数量呢&#xff1f;Tokeniser包可以有效地计算文本输入中的令牌来估算这些成本。本文将介绍如何使用Tokeniser有效地预测和管…

异步编程实战:使用C#实现FTP文件下载及超时控制

博客标题: 异步编程实战&#xff1a;使用C#实现FTP文件下载及超时控制 如果你的函数不是async&#xff0c;你仍然可以实现相同的超时功能&#xff0c;但你将不得不依赖更多的同步代码或使用.Result或.GetAwaiter().GetResult()来阻塞等待任务完成&#xff0c;这可能导致死锁的风…

verilog中的函数和for循环

在Verilog中&#xff0c;clogb2 的英文全称是 “ceiling&#xff08;天花板&#xff09; log base 2”&#xff0c;表示对输入参数取对数&#xff08;以2为底&#xff09;&#xff0c;并向上取整到最接近的整数值。这个函数通常用于计算内存地址宽度或状态数所需的位数12。 fun…

STM32---通用定时器(二)相关实验

写在前面&#xff1a;前面我们学习了基本定时器、通用定时器的相关理论部分&#xff0c;了解到通用定时器的结构框图&#xff0c;总共包含六大模块&#xff1a;时钟源、控制器、时基单元、输入捕获、公共部分以及输出捕获。对相关模块的使用也做详细的讲解。本节我们主要是对上…

Day33-计算机基础3

Day33-计算机基础3 1.根据TCP/IP进行Linux内核参数优化1.1 例1&#xff1a;调整访问服务端的【客户端】的动态端口范围 &#xff0c;LVS&#xff08;10-50万并发&#xff09;&#xff0c;NGINX负载&#xff0c;SQUID缓存服务,1.2 企业案例&#xff1a;DOS攻击的案例&#xff1a…

[备赛笔记]——5G大唐杯(5G考试等级考考试基础试题)

个人名片&#xff1a; &#x1f981;作者简介&#xff1a;学生 &#x1f42f;个人主页&#xff1a;妄北y &#x1f427;个人QQ&#xff1a;2061314755 &#x1f43b;个人邮箱&#xff1a;2061314755qq.com &#x1f989;个人WeChat&#xff1a;Vir2021GKBS &#x1f43c;本文由…

redis缓存满了的话会发生什么?

线上问题 未及时加监控&#xff0c;导致线上redis被逐出&#xff0c;业务有损 示例&#xff1a; 一个key临时存储在redis等缓存中&#xff0c;如果该key在一段时间内有很大作用 比如一次业务请求&#xff0c;上游服务写入一个value&#xff0c;时长1小时&#xff0c;下游服务…

Matlab|考虑源荷两侧不确定性的含风电电力系统低碳调度

目录 1 主要内容 目标函数&#xff1a; 约束条件&#xff1a; 程序亮点总结&#xff1a; 2 代码问题与程序测试 设备出力运行结果&#xff1a; 3 下载链接 1 主要内容 本程序是对《考虑源荷两侧不确定性的含风电电力系统低碳调度》的方法复现&#xff0c;主要实现了基…

【QT+QGIS跨平台编译】之七十六:【QGIS_Native+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

文章目录 一、QGIS_Native介绍二、QGIS下载三、文件分析四、pro文件五、编译实践一、QGIS_Native介绍 QGIS_Native模块是QGIS软件的核心部分,提供了许多基本功能和核心组件,主要用于处理与底层操作系统的关系。 二、QGIS下载 QGIS网址: QGIS Source Download 三、文件分析…

Django学习笔记

Django学习笔记 一、Django整体流程跑通 1.1安装 pip install django //安装 import django //在python环境中导入django django.get_version() //获取版本号&#xff0c;如果能获取到&#xff0c;说明安装成功Django目录结构 Python310-Scripts\django-admi…