【python】flask中ORM工具SQLAIchemy,各种数据查询操作详细解析

news2024/12/29 9:31:55

在这里插入图片描述

✨✨ 欢迎大家来到景天科技苑✨✨

🎈🎈 养成好习惯,先赞后看哦~🎈🎈

🏆 作者简介:景天科技苑
🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。
🏆《博客》:Python全栈,前后端开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi,flask等框架,linux,shell脚本等实操经验,网站搭建,面试宝典等分享。

所属的专栏:flask框架零基础,进阶应用实战教学
景天的主页:景天科技苑

文章目录

  • 基本查询
    • SQLAlchemy常用的查询过滤器
    • get():参数为主键,表示根据主键查询数据,如果主键不存在返回None
    • all()返回查询到的所有对象
    • count() 返回查询结果的数量
    • first()返回查询到的第一个对象
  • filter条件查询
    • 基于filter进行模糊查询
    • 基于filter进行比较查询
    • filter_by精确条件查询
  • 逻辑查询
    • 逻辑与,需要导入`and_`,返回`and_()`条件满足的所有数据
    • 逻辑或,需要导入or_
    • 逻辑非,返回名字不等于"小白"的所有数据
    • not_ 相当于取反
    • in_范围查询
    • is_判断值查询
    • order_by 排序
    • 对查询结果进行偏移量和数量的限制
  • 总结

Hello,大家好,我是景天,前面我们讲到flask的ORM工具的增删改,其实工作中,我们用的较多的还是数据的查询,今天我们就SQLAIchemy的各种查询方式来详细展开!!!

基本查询

SQLAlchemy常用的查询过滤器

filter是模糊查询,filter_by是精确查询
在这里插入图片描述

SQLAlchemy常用的查询结果方法
在这里插入图片描述

get():参数为主键,表示根据主键查询数据,如果主键不存在返回None

查询之前,先看下数据库数据
在这里插入图片描述

@app.route("/get")
def get():
    """按主键获取一条,有以下几种查询方式"""
    # student = Student.query.get({"id": 4})
    # student = Student.query.get((4,))
    # student = db.session.query(Student).get(4)
    student = Student.query.get(4)
    print(student)
    return "ok"

浏览器访问/get ,拿到数据
在这里插入图片描述

all()返回查询到的所有对象

# 如果不设置条件,则默认查询全表
student_list = Student.query.all()
print(student_list)

# 设置过滤条件查询全部结果
# 如果查不到数据,返回空列表
student_list = Student.query.filter(Student.sex==False).all()
print(student_list)

# all()的返回值是一个python列表,可以直接使用切片,与django的QuerySet完全不是一回事。
student_list = Student.query.all()[1:]
print(student_list)

在这里插入图片描述

count() 返回查询结果的数量

# 如果不设置过滤条件,则默认统计全表记录的数量
total = Student.query.count()
print(total)

# 设置条件,作为返回满足条件的记录数量
total = Student.query.filter(Student.age>16).count()
print(total)

在这里插入图片描述

first()返回查询到的第一个对象

【first的结果只有一个模型对象】

"""获取查询结果的第一个结果"""
student = Student.query.first()
print(student, student.name)

student = Student.query.filter(Student.sex==True).first()
print(student, student.name)

"""获取查询结果的第二个结果,现在不支持负索引了"""
student = Student.query.filter(Student.sex==True)[1]
print(student, student.name)

在这里插入图片描述

filter条件查询

支持各种运算符和查询方法或者模糊查询方法。

基于filter进行模糊查询

# 名字包含"黑"的学生
student_list = Student.query.filter(Student.name.contains("黑")).all()
print(student_list)

# 名字以"小"开头的学生
student_list = Student.query.filter(Student.name.startswith("小")).all()
print(student_list)

# 名字以"红"结尾的学生
student_list = Student.query.filter(Student.name.endswith("兰")).all()
print(student_list)

在这里插入图片描述

基于filter进行比较查询

# 比较查询需要指定条件格式为: filter(模型.字段 比较运算符 值)。
# 运算符可以是: ==表示相等, !=不相等,> 表示大于  < 表示小于,>=大于等于,<=小于等于
# 单个条件的比较查询
student_list = Student.query.filter(Student.age>15).all()
print(student_list)

# 多个条件的比较查询
# 要求多个条件都要满足,相当于逻辑查询中的 并且(and)!!
student_list = Student.query.filter(Student.age>15, Student.sex==True).all()
print(student_list)

在这里插入图片描述

filter_by精确条件查询

filter_by 只支持字段的值是否相等的情况,对于大于、小于、大于等于、等等其他条件是不支持的。

例如:返回age等于16的学生

# 单条件格式:filter_by(字段=值)
# 多条件格式:filter_by(字段=值, 字段=值, 字段=值...)
student_list = Student.query.filter_by(age=16).all()  # 字段添加不需要附带模型类
print(student_list)

在这里插入图片描述

逻辑查询

逻辑与,需要导入and_,返回and_()条件满足的所有数据

 # 默认情况下, 多个条件并且的情况,可以直接基于filter或者filter_by采用逗号拼接多个查询条件实现
# 查询年龄大于16的男生
student_list = Student.query.filter(Student.age>16, Student.sex==True).all()
print("第一次",student_list)

#  filter(and_(条件1,条件2,....))  等价于  filter(条件1,条件2,.....)
from sqlalchemy import and_
student_list = Student.query.filter(and_(Student.age>16, Student.sex==True)).all()
print("第二次",student_list)

在这里插入图片描述

逻辑或,需要导入or_

# # 查询年龄大于16(Student.age>16)或者钱包余额大于1500(Student.money>1500) 女生
from sqlalchemy import or_
student_list = Student.query.filter(or_(Student.age>16, Student.money>1500), Student.sex==False).all()
print("第一次",student_list)

# 查询 年龄大于16的男生(Student.age>16, Student.sex==True) 和 钱包余额大于1500的女生(Student.money>1500, Student.sex==False)
from sqlalchemy import or_, and_
student_list = Student.query.filter(
    or_(
        and_(Student.age>16, Student.sex==True),
        and_(Student.money>1500, Student.sex==False)
    )
).all()
print("第二次",student_list)

在这里插入图片描述

逻辑非,返回名字不等于"小白"的所有数据

#逻辑非
student = Student.query.filter(Student.name != '小白').all()
print(student)

在这里插入图片描述

not_ 相当于取反

from sqlalchemy import not_
student = Student.query.filter(Student.name != '小白').all()
print("第一次",student)

student = Student.query.filter(not_(Student.name == '小白')).all()
print("第二次",student)

在这里插入图片描述

in_范围查询

student_list = Student.query.filter(Student.id.in_([1,3,4,5])).all()
print(student_list)

在这里插入图片描述

is_判断值查询

# 查询邮箱为Null的用户
student_list = Student.query.filter(Student.email.is_(None)).all()
print(student_list)

"""判断是否存在"""
# 查询是否存在"小辉"这个学生
query = Student.query.filter(Student.name == "小辉").exists()
#通过scalar()拿到查询是否存在
ret = db.session.query(query).scalar()
print("第一次是否存在",ret)

student = Student.query.filter(Student.name=="小明").first()
print("第二次是否存在",bool(student))

在这里插入图片描述

order_by 排序

# 按年龄倒叙排序
student_list = Student.query.order_by(Student.age.desc()).all()
print(student_list)

# 按钱包余额进行倒序,如果余额一致,按id倒序
student_list = Student.query.order_by(Student.money.desc(), Student.id.desc()).all()
print(student_list)

在这里插入图片描述

对查询结果进行偏移量和数量的限制

#查询年龄最大的三个人
student_list = Student.query.order_by(Student.age.desc()).limit(3).all()
print(student_list)

# 查询钱包余额最少的三个人
student_list = Student.query.order_by(Student.money.asc()).limit(3).all()
print(student_list)

# 按钱包余额进行倒序排列,查询出排名在4-5之间的学生
student_list = Student.query.order_by(Student.money.desc()).offset(3).limit(2).all()
print(student_list)

student_list = Student.query.order_by(Student.money.desc()).all()[3:5]
print(student_list)

在这里插入图片描述

完整代码

from flask import Flask
from flask_sqlalchemy import SQLAlchemy


app = Flask(__name__)
# 连接数据库连接url
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:Jinghao31357!@10.10.0.52:3306/students?charset=utf8mb4"
# 动态追踪修改设置,如未设置只会提示警告
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = True
# 查询时会显示原始SQL语句
app.config["SQLALCHEMY_ECHO"] = True

# 把SQLAlchemy组件注册到项目中
db = SQLAlchemy()
db.init_app(app)


#创建模型类
class Student(db.Model):
    """学生信息模型"""

    # 声明与当前模型绑定的数据表名称
    __tablename__ = "tb_student2"
    id = db.Column(db.Integer, primary_key=True, comment="主键")
    name = db.Column(db.String(15), index=True, comment="姓名")
    age = db.Column(db.SmallInteger, comment="年龄")
    sex = db.Column(db.Boolean, default=True, comment="性别")
    email = db.Column(db.String(128), unique=True, comment="邮箱地址")
    money = db.Column(db.Numeric(10, 2), default=0.0, comment="钱包")

    def __repr__(self):  # 相当于django的__str__
        return f"{self.name}<{self.__class__.__name__}>"


class Course(db.Model):
    """课程模型"""

    __tablename__ = "tb_course"
    id = db.Column(db.Integer, primary_key=True, comment="主键")
    name = db.Column(db.String(255), unique=True, comment="课程")
    price = db.Column(db.Numeric(8, 2), comment="价格")

    def __repr__(self):  # 相当于django的__str__
        return f"{self.name}<{self.__class__.__name__}>"



class Teacher(db.Model):
    """老师模型"""
    __tablename__ = "tb_teacher"
    id = db.Column(db.Integer, primary_key=True, comment="主键")
    name = db.Column(db.String(255), unique=True, comment="姓名")
    #枚举类型
    option = db.Column(db.Enum("讲师", "助教", "班主任"), default="讲师")

    def __repr__(self):
        return f"{self.name}<{self.__class__.__name__}>"



@app.route("/get")
def get():
    """按主键获取一条,有以下几种查询方式"""
    # student = Student.query.get({"id": 4})
    # student = Student.query.get((4,))
    # student = db.session.query(Student).get(4)
    # student = Student.query.get(4)
    # print(student)

    #
    # # 如果不设置条件,则默认查询全表
    # student_list = Student.query.all()
    # print(student_list)
    #
    # # 设置过滤条件查询全部结果
    # # 如果查不到数据,返回空列表
    # student_list = Student.query.filter(Student.sex==False).all()
    # print(student_list)
    #
    # # all()的返回值是一个python列表,可以直接使用切片,与django的QuerySet完全不是一回事。
    # student_list = Student.query.all()[1:]
    # print(student_list)



    #count返回查询结果数量
    # 如果不设置过滤条件,则默认统计全表记录的数量
    # total = Student.query.count()
    # print(total)
    #
    # # 设置条件,作为返回满足条件的记录数量
    # total = Student.query.filter(Student.age>16).count()
    # print(total)


    # """first()获取查询结果的第一个结果"""
    # student = Student.query.first()
    # print(student, student.name)
    #
    # student = Student.query.filter(Student.sex==True).first()
    # print(student, student.name)
    #
    # """获取查询结果的第二个结果"""
    # student = Student.query.filter(Student.sex==True)[1]
    # # print(student, student.name)
    # print("查询结果",student)



    # # 名字包含"黑"的学生
    # student_list = Student.query.filter(Student.name.contains("黑")).all()
    # print(student_list)
    #
    # # 名字以"小"开头的学生
    # student_list = Student.query.filter(Student.name.startswith("小")).all()
    # print(student_list)
    #
    # # 名字以"红"结尾的学生
    # student_list = Student.query.filter(Student.name.endswith("兰")).all()
    # print(student_list)



    # # 比较查询需要指定条件格式为: filter(模型.字段 比较运算符 值)。
    # # 运算符可以是: ==表示相等, !=不相等,> 表示大于  < 表示小于,>=大于等于,<=小于等于
    # # 单个条件的比较查询
    # student_list = Student.query.filter(Student.age>15).all()
    # print(student_list)
    #
    # # 多个条件的比较查询
    # # 要求多个条件都要满足,相当于逻辑查询中的 并且(and)!!
    # student_list = Student.query.filter(Student.age>15, Student.sex==True).all()
    # print(student_list)



    # 单条件格式:filter_by(字段=值)
    # 多条件格式:filter_by(字段=值, 字段=值, 字段=值...)
    # student_list = Student.query.filter_by(age=16).all()  # 字段添加不需要附带模型类
    # print(student_list)
    #



    # # 默认情况下, 多个条件并且的情况,可以直接基于filter或者filter_by采用逗号拼接多个查询条件实现
    # # 查询年龄大于16的男生
    # student_list = Student.query.filter(Student.age>16, Student.sex==True).all()
    # print("第一次",student_list)
    #
    # #  filter(and_(条件1,条件2,....))  等价于  filter(条件1,条件2,.....)
    # from sqlalchemy import and_
    # student_list = Student.query.filter(and_(Student.age>16, Student.sex==True)).all()
    # print("第二次",student_list)



    # # 查询年龄大于16(Student.age>16)或者钱包余额大于1500(Student.money>1500) 女生
    # from sqlalchemy import or_
    # student_list = Student.query.filter(or_(Student.age>16, Student.money>1500), Student.sex==False).all()
    # print("第一次",student_list)
    #
    # # 查询 年龄大于16的男生(Student.age>16, Student.sex==True) 和 钱包余额大于1500的女生(Student.money>1500, Student.sex==False)
    # from sqlalchemy import or_, and_
    # student_list = Student.query.filter(
    #     or_(
    #         and_(Student.age>16, Student.sex==True),
    #         and_(Student.money>1500, Student.sex==False)
    #     )
    # ).all()
    # print("第二次",student_list)

    # #逻辑非
    # student = Student.query.filter(Student.name != '小白').all()
    # print(student)

    # from sqlalchemy import not_
    # student = Student.query.filter(Student.name != '小白').all()
    # print("第一次",student)
    #
    # student = Student.query.filter(not_(Student.name == '小白')).all()
    # print("第二次",student)


    # student_list = Student.query.filter(Student.id.in_([1,3,4,5])).all()
    # print(student_list)


    # 查询邮箱为Null的用户
    # student_list = Student.query.filter(Student.email.is_(None)).all()
    # print(student_list)
    #
    # """判断是否存在"""
    # # 查询是否存在"小辉"这个学生
    # query = Student.query.filter(Student.name == "小辉").exists()
    # #通过scalar()拿到查询是否存在
    # ret = db.session.query(query).scalar()
    # print("第一次是否存在",ret)
    #
    # student = Student.query.filter(Student.name=="小明").first()
    # print("第二次是否存在",bool(student))



    # # 按年龄倒叙排序
    # student_list = Student.query.order_by(Student.age.desc()).all()
    # print(student_list)
    #
    # # 按钱包余额进行倒序,如果余额一致,按id倒序
    # student_list = Student.query.order_by(Student.money.desc(), Student.id.desc()).all()
    # print(student_list)



    #查询年龄最大的三个人
    student_list = Student.query.order_by(Student.age.desc()).limit(3).all()
    print(student_list)

    # 查询钱包余额最少的三个人
    student_list = Student.query.order_by(Student.money.asc()).limit(3).all()
    print(student_list)

    # 按钱包余额进行倒序排列,查询出排名在4-5之间的学生
    student_list = Student.query.order_by(Student.money.desc()).offset(3).limit(2).all()
    print(student_list)

    student_list = Student.query.order_by(Student.money.desc()).all()[3:5]
    print(student_list)





    return "ok"




if __name__ == '__main__':
    #要想执行创建表,需要调用db.creat_all(),db要想被调用,需要放到app上下文里面
    with app.app_context():
        # 如果没有提前声明模型中的数据表,则可以采用以下代码生成数据表,
        # 如果数据库中已经声明了有数据表,则不会继续生成
        db.create_all()
    app.run(debug=True)

总结

本文详述了flask的ORM工具SQLAlchemy各种数据查询的详细用法,包含基础查询和各种复杂查询,非常实用,感兴趣的朋友可以一键三连,flask的高阶用法持续更新中!!!

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

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

相关文章

在Windows中使用WSL访问EXT4分区的完整指南

目录标题 1. 挂载步骤2. 卸载步骤3.在wsl中配置分区自动加载 众所周知&#xff0c;要想在windows上面访问ext4 linux分区还是很费劲的。之前有开源的ext2fsd方案&#xff0c;或者用paragon提供的付费版本的Paragon ExtFS。前者已经很久没有更新了&#xff0c;稳定性和可靠性是个…

云轴科技ZStack入选中国信通院《高质量数字化转型产品及服务全景图(2023年度)》

近日&#xff0c;由中国互联网协会主办、中国信通院承办的“2024高质量数字化转型创新发展大会”暨“铸基计划”年度会议在北京成功召开。 本次大会发布了2024年度行业数字化转型趋势&#xff0c;总结并展望了“铸基计划”2023年取得的工作成果及2024年的工作规划。同时&#…

Object.assign()用法及详细分析到底是浅拷贝还是深拷贝?

Object.assign方法用于对象的合并&#xff0c;将源对象&#xff08;source &#xff09;的所有可枚举属性&#xff0c;复制到目标对象&#xff08;target&#xff09;。 Object.assign(target,source1,source2) Object.assign方法的第一个参数是目标对象&#xff0c;后面的参数…

SD-WAN解决电商企业海外业务网络难题

全球化背景下&#xff0c;众多国内企业都涉及到海外贸易业务&#xff0c;尤其是出海电商得到蓬勃发展。企业做出海电商&#xff0c;需要访问国外网页、社交平台&#xff0c;如亚马逊、TikTok、Facebook、YouTube等与客户沟通互动&#xff0c;SD-WAN的发展正好为解决国际网络访问…

43.HarmonyOS鸿蒙系统 App(ArkUI)@State$单引号引用变量失败--解决方法

HarmonyOS鸿蒙系统 App(ArkUI)$单引号引用变量失败--解决方法 State name2:string 反引号键 $加大括号来引用变量&#xff0c;不是使用的单引号&#xff0c;而是反引号&#xff0c;在键盘的Esc键的下面 Entry Componentstruct Index {State message: string Hello WorldStat…

鸿蒙TypeScript学习第19天【命名空间】

1、TypeScript 命名空间 命名空间一个最明确的目的就是解决重名问题。 假设这样一种情况&#xff0c;当一个班上有两个名叫小明的学生时&#xff0c;为了明确区分它们&#xff0c;我们在使用名字之外&#xff0c;不得不使用一些额外的信息&#xff0c;比如他们的姓&#xff0…

.netcore+vue新生分班系统的设计与实现

.netcore vue新生分班系统的设计与实现说明文档 运行前附加数据库.mdf&#xff08;或sql生成数据库&#xff09; 主要技术&#xff1a; 基于.net core架构和mysql数据库vue 东北石油大学新生分班系统的设计与实现 功能模块&#xff1a; 登录 注册学生 忘记密码 系统首顶 个…

【电控笔记3.5】三相逆变器

基础 大小调变指标ma 频率调变指标mf 载波频率:pwm频率

PHP校验15位和18位身份证号

第十八位数字的计算方法为&#xff1a; 1.将前面的身份证号码17位数分别乘以不同的系数。从第一位到第十七位的系数分 别为&#xff1a;7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 2.将这17位数字和系数相乘的结果相加。 3.用加出来和除以11&#xff0c;看余数是多少&#xff1f; 4…

遇事不决 量子力学?

文章目录 引入量子力学产生的必然性量子力学名称的由来粒子&#xff1f;波&#xff1f;波粒二象性测不准原理 &#xff08;不确定原理&#xff09;叠加态原理 量子纠缠态叠加量子纠缠量子纠缠实验 逻辑判断&#xff0c;量子力学到底完善吗观测量子纠缠&#xff1f;那我们宏观世…

AUS Global 与皇家贝蒂斯俱乐部在对战皇家马德里的比赛日举办现场体验活动

AUS Global 最近前往西班牙庆祝与皇家贝蒂斯的赞助合作&#xff0c;并获得了难忘的比赛日体验&#xff0c;包括在贵宾室中观看皇家贝蒂斯对阵皇家马德里的精彩比赛。 活动开始时&#xff0c;AUS Global 受邀来到皇家贝蒂斯主场贝尼托-比利亚马林体育场的独家 Showbox 贵宾室。…

vue3 源码解析(7)— diff 算法源码的实现

前言 vue3 采用的 diff 算法名为快速 diff 算法&#xff0c;整个 diff 的过程分为以下5个阶段完成。 处理前置节点处理后置节点处理仅有新增节点处理仅有删除节点处理其他情况&#xff08;新增 / 卸载 / 移动&#xff09; 这里我们先定义新旧两个节点列表&#xff0c;接下来…

4款免费又好用的AI工具!很难相信!

人工智能&#xff08;AI&#xff09;已经成为我们生活和工作中不可或缺的一部分。但是&#xff0c;一提到AI工具&#xff0c;你可能首先会想到的是高昂的价格和复杂的操作。 今天&#xff0c;君君就要打破这一刻板印象&#xff0c;带你认识4个AI工具&#xff0c;它们不仅功能强…

《QT实用小工具·二十七》各种炫酷的样式表

1、概述 源码放在文章末尾 该项目实现了各种炫酷的样式表&#xff0c;如单选、多选、按钮、日历、表格、下拉框、滚轮等&#xff0c;下面是项目demo演示&#xff1a; 项目部分代码如下&#xff1a; #include "frmmain.h" #include "ui_frmmain.h" #inc…

数仓建模—数据架构

数仓—数据架构 为了在企业决策中使用数据,数据必须经过整个数据平台的各个阶段。整个过程是什么样子的,从开始到结束?原始形式的数据是如何转化为可导致商业决策的见解的?这些问题可以通过数据架构来回答。 数据架构是指记录组织所有数据资产的模型、规则和标准。它映射…

Zephyr Windows开发环境搭建

Zephyr 如果有错误或未及时更新&#xff0c;请以官网文档为主 官网&#xff1a;https://docs.zephyrproject.org/latest/develop/getting_started/index.htm 下载安装 Chocolatey 这是一个类似于在Linux系统下 yum 和 apt 那样的包管理器 官网&#xff1a;https://chocolat…

平衡车设计——硬件篇

在本文开始之前我忍不住想吐槽一个事情&#xff0c;就在前两天晚上&#xff0c;我满意地装完平衡车&#xff0c;给他取了个名字叫瓦力&#xff08;没错&#xff0c;就是机器人总动员里的瓦力&#xff09;&#xff0c;他长这个样子。 把他放到桌子上放了一夜&#xff0c;第二天早…

【vue】Pinia-2 安装Pinia,使用store

1. 安装Pinia 在项目路径下执行npm install pinia 在package.json中查看 2. 使用store 在main.js中添加 import { createPinia } from pinia const pinia createPinia()修改createApp方法 最后示例如下&#xff08;三处修改&#xff09; import { createApp } from vue //…

Jmeter接口测试:使用教程(下)

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 关注公众号&#xff1a;互联网杂货铺&#xff0c;回复1 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 上一篇我给大家讲了jmeter的基本介绍跟参数化和jmeter脚…

【开发者召集】BIMBase插件开发大赛火热报名中!| python开发 | python建模 | 二次开发 | 图形引擎 | 几何引擎

&#x1f4e2; 致所有热爱创新的技术大咖们&#xff1a; 让我们回顾一下&#xff0c;在之前的推文中&#xff0c;我们收集了各种各样的BIM插件命题~ 小伙伴们的热情让小编倍感振奋~ 因为&#xff0c;每一个命题都蕴藏着解决实际问题的潜力&#xff0c;每一个也都代表着创新的可…