当前位置:首页 » 《我的小黑屋》 » 正文

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

4 人参与  2024年04月19日 08:47  分类 : 《我的小黑屋》  评论

点击全文阅读


在这里插入图片描述

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

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

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

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

文章目录

基本查询SQLAlchemy常用的查询过滤器get():参数为主键,表示根据主键查询数据,如果主键不存在返回Noneall()返回查询到的所有对象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 Flaskfrom flask_sqlalchemy import SQLAlchemyapp = Flask(__name__)# 连接数据库连接urlapp.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://zhangshiyu.com/post/97379.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1