✨✨ 欢迎大家来到景天科技苑✨✨
🎈🎈 养成好习惯,先赞后看哦~🎈🎈
🏆 作者简介:景天科技苑
🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,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的高阶用法持续更新中!!!