Flask-SQLAlchemy数据库查询:query

1、为什么可以用 模型类.query 来查询数据库?

在 Flask 中使用 SQLAlchemy ORM 时,所有继承自 db.Model 的模型类都会自动获得一个 query 属性。

其本质是 db.session.query(模型类) 的快捷方式,无需显式操作 db.session

代码示例,比如定义一个继承自 db.Model 的模型类 CommonModel

from flask_sqlalchemy import SQLAlchemy  
db = SQLAlchemy()  # 初始化 SQLAlchemy 实例  # 定义模型类(继承自 db.Model)  
class CommonModel(db.Model):  id = db.Column(db.Integer, primary_key=True)  # 其他字段...  

以下两种写法等价

# 写法 1:通过模型类的 query 属性(隐式绑定会话)  
result1 = CommonModel.query.filter_by(field='value').first()  # 写法 2:通过 db.session 显式绑定模型类  
result2 = db.session.query(CommonModel).filter_by(field='value').first()  

2、基础查询

2.1、如何定义查询:设置过滤条件

2.1.1、get(primary_key):按主键精准定位
  • 作用:通过模型类的主键(如 id)直接定位单条记录,是主键查询的最优选择。
  • 优势:直接利用数据库主键索引,查询效率最高
  • 示例(以 User 模型为例):
    user = User.query.get(1)  # 查询 ID 为 1 的用户(存在返回实例,不存在返回 None)  
    
2.1.2、filter_by(**kwargs):基于关键字的简单等值过滤
  • 作用:通过模型类属性的等值条件(如 username='alice')过滤记录。
  • 限制:仅支持等值查询(=),无法处理范围(>, <)或模糊查询(LIKE)。
  • 示例(以 User 模型为例):
    active_users = User.query.filter_by(is_active=True).all()  # 查询所有活跃用户  
    
2.1.3、filter(条件表达式):灵活的多条件查询
  • 作用:支持范围、模糊、逻辑与/或等复杂条件,是 filter_by 的增强版。
  • 语法:通过模型类属性构建表达式(如 User.age > 18)。
  • 示例(以 User 模型为例):
    from datetime import datetime  
    from sqlalchemy import or_  # 查询 2023 年后注册且邮箱以 'example.com' 结尾的用户(范围+模糊)  
    users = User.query.filter(  User.registered_at > datetime(2023, 1, 1),  User.email.like('%@example.com')  
    ).all()  # 查询年龄大于 18 或用户名含 'test' 的用户(逻辑或)  
    users = User.query.filter(  or_(User.age > 18, User.username.like('%test%'))  
    ).all()  
    
2.1.4、order_by(字段表达式):按字段排序
  • 作用:指定结果的排序规则(正序 / 倒序)。
  • 语法:通过模型类属性指定排序字段(如 User.registered_at.desc() 倒序)。
  • 示例
# 按注册时间倒序(最新注册在前)  
recent_users = User.query.order_by(User.registered_at.desc()).all()  # 先按年龄正序,再按注册时间倒序(多字段排序)  
users = User.query.order_by(User.age.asc(), User.registered_at.desc()).all()  
2.1.5、with_entities(字段列表):仅查询指定字段
  • 作用:仅返回指定字段的数据(减少数据传输量)。
  • 示例
# 仅查询用户的 ID 和用户名  
user_ids = User.query.with_entities(User.id, User.username).all()  # 返回 [(1, 'alice'), (2, 'bob')...]  

2.2、如何获取结果:提取查询数据

定义查询条件后,需通过方法提取最终结果集(单条、多条、统计值或特定聚合值)。

2.2.1、first():获取首条记录
  • 作用:返回查询结果中的第一条记录(无结果返回 None)。
  • 适用场景:已知查询结果最多一条(如用户登录验证)。
  • 示例(以 User 模型为例):
    user = User.query.filter_by(username='alice').first()  # 查找用户名为 'alice' 的用户(可能不存在)  
    
2.2.2、all():获取所有符合条件的记录
  • 作用:返回查询结果的所有记录(列表,无结果返回空列表 [])。
  • 适用场景:需要批量处理数据(如展示用户列表)。
  • 示例(以 User 模型为例):
    users = User.query.filter(User.age > 18).all()  # 查找所有年龄大于 18 的用户(可能为空列表)  
    
2.2.3、one():严格获取单条记录(无结果或多结果抛异常)
  • 作用:要求查询结果必须恰好一条,否则抛出异常(NoResultFoundMultipleResultsFound)。
  • 适用场景:业务逻辑要求结果唯一(如查询“当前生效的配置”)。
  • 示例(以 Config 模型为例):
    from sqlalchemy.exc import NoResultFound, MultipleResultsFound  try:  current_config = Config.query.filter_by(is_active=True).one()  
    except NoResultFound:  print("无生效配置!")  
    except MultipleResultsFound:  print("存在多个生效配置,需检查数据!")  
    
2.2.4、count():统计结果数量
  • 作用:直接执行 SELECT COUNT(*),高效统计符合条件的记录总数。
  • 优势:避免加载所有数据,性能优于 len(all())
  • 示例(以 User 模型为例):
 # 统计活跃用户数量(返回整数)active_count = User.query.filter_by(is_active=True).count()    
2.2.5、limit(n):限制返回数量
  • 作用:仅返回前 n 条记录。
  • 示例
# 获取分数最高的前 5 个用户
top_5_users = User.query.order_by(User.score.desc()).limit(5).all()   
2.2.6、offset(n):跳过前 n 条记录
  • 作用:结合 limit 实现分页(如跳过前 10 条,取后 10 条)。
  • 示例
# 第 2 页数据(每页 10 条)
page_2_users = User.query.order_by(User.id).offset(10).limit(10).all()    
2.2.7、使用 paginate() 处理大数据分页

通过 paginate() 封装 offsetlimit,自动处理分页逻辑,避免一次性加载大量数据:

# 获取第 2 页,每页 10 条数据(自动处理越界)  
page_obj = User.query.order_by(User.registered_at.desc()).paginate(page=2, per_page=10)  
current_users = page_obj.items  # 当前页数据  
total_pages = page_obj.pages  # 总页数  

3、关联查询:处理表间关系与预加载优化

在实际项目中,模型类间通常存在关联(如用户与帖子的一对多关系)。
通过 relationship 字段定义关联后,需结合预加载优化避免 N+1 查询问题。

3.1、模型类关联关系定义(以用户-帖子为例)

class Post(db.Model):  id = db.Column(db.Integer, primary_key=True)  title = db.Column(db.String(200))  author_id = db.Column(db.Integer, db.ForeignKey('user.id'))  # 外键关联用户 ID  class User(db.Model):  id = db.Column(db.Integer, primary_key=True)  username = db.Column(db.String(80))  # 定义一对多关系:user.posts 可获取用户所有帖子  posts = db.relationship('Post', backref='author', lazy='select')  # backref 为 post.author 提供反向引用  
  • backref:在关联模型(如 Post)中自动创建反向引用(post.author 可获取用户实例)。
  • lazy:控制关联数据的加载时机(默认 'select',即访问时加载)。

3.2、预加载优化:避免 N+1 查询

直接访问关联数据(如 user.posts)时,SQLAlchemy 默认会触发多次查询(N+1 问题)。通过 joinedload 预加载,可一次性加载关联数据,减少数据库交互。

示例:未优化的 N+1 查询

# 查询 10 个用户,并获取他们的帖子(触发 1(用户查询) + 10(帖子查询)次 SQL)  
users = User.query.limit(10).all()  
for user in users:  print(user.posts)  # 每次循环触发一次帖子查询  

示例:优化后的预加载查询

from sqlalchemy.orm import joinedload  # 一次性加载用户及其帖子(仅 1 次 SQL)  
users = User.query.options(joinedload(User.posts)).limit(10).all()  
for user in users:  print(user.posts)  # 数据已预加载,无额外查询  

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

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

相关文章

【免费】【无需登录/关注】度分秒转换在线工具

UVE Toolbox 功能概述 这是一个用于地理坐标转换的在线工具&#xff0c;支持两种转换模式&#xff1a; 十进制度 → 度分秒 度分秒 → 十进制度 使用方法 十进制度转度分秒 在"经度"输入框中输入十进制度格式的经度值&#xff08;例如&#xff1a;121.46694&am…

怎么判断一个Android APP使用了React Native 这个跨端框架

要判断一个 Android 应用是否使用了 React Native 框架&#xff0c;可以通过以下方法逐步验证&#xff1a; 一、安装包结构分析 1. 解压 APK 将 .apk 文件重命名为 .zip 并解压&#xff0c;检查以下特征文件&#xff1a; • assets/index.android.bundle&#xff1a; React Na…

Pluto实验报告——基于2ASK的简易的通信系统

一、实验目的 1. 熟悉并掌握PLUTO SDR 主动学习模块的使用&#xff1b; 2.通过matlab 编码与adalm pluto 相配合达成一个简易的通信系统&#xff0c;并能 够传输一些较为简单的信息。 二、实验原理 2ASK 调制原理&#xff1a; 振幅键控是指利用载波的振幅变化来传递数字基带信…

Ubuntu 24-部署FTP和自定义用户

目录 一、 安装 vsftpd 二、创建 FTP 数据目录 三、创建 FTP 用户 四、配置 vsftpd 五、重启 vsftpd 服务 六、增加新用户脚本 一、 安装 vsftpd sudo apt update sudo apt install vsftpd -y 二、创建 FTP 数据目录 sudo mkdir -p /data/ftp sudo chown nobody:nogrou…

MySQL问题:什么是MySQL的中的最左匹配原则?

是指在复合索引中&#xff0c;查询条件需要按照索引列的顺序从最左侧列开始依次匹配。只有查询条件中的列按照索引的最左边列开始进行匹配&#xff0c;索引才能被有效使用&#xff0c;但有时虽然不是正常顺序&#xff0c;由于MySQL中存在优化器&#xff0c;会自动调整顺序&…

2025软考软件设计师题目

选择题&#xff08;综合题&#xff09; 确定得分的 1、Linux外设目录是什么 /dev。存储磁盘的目录 2、Linux外设sdc类型设备属于什么 scsi hard disk。根据第一个字母s盲猜的 3、计算机中让程序计数器PC不能指向当前运行程序的技术是 流水线。根据流水线的原理 4、Python程…

Deep Evidential Regression

摘要 翻译&#xff1a; 确定性神经网络&#xff08;NNs&#xff09;正日益部署在安全关键领域&#xff0c;其中校准良好、鲁棒且高效的不确定性度量至关重要。本文提出一种新颖方法&#xff0c;用于训练非贝叶斯神经网络以同时估计连续目标值及其关联证据&#xff0c;从而学习…

每天掌握一个Linux命令 - sqlite3

Linux 命令工具 sqlite3 使用指南 一、工具概述 sqlite3 是 SQLite 数据库的命令行工具&#xff0c;用于在 Linux 系统中直接操作 SQLite 数据库&#xff08;轻量级、无服务器、嵌入式关系型数据库&#xff09;。 核心特点&#xff1a; 无需安装数据库服务&#xff0c;直接通…

leetcode:2160. 拆分数位后四位数字的最小和(python3解法,数学相关算法题)

难度&#xff1a;简单 给你一个四位 正 整数 num 。请你使用 num 中的 数位 &#xff0c;将 num 拆成两个新的整数 new1 和 new2 。new1 和 new2 中可以有 前导 0 &#xff0c;且 num 中 所有 数位都必须使用。 比方说&#xff0c;给你 num 2932 &#xff0c;你拥有的数位包括…

Python打卡第38天

浙大疏锦行 作业&#xff1a; 了解下cifar数据集&#xff0c;尝试获取其中一张图片 import torch import torch.nn as nn import torch.optim as optim from torch.utils.data import DataLoader , Dataset # DataLoader 是 PyTorch 中用于加载数据的工具 from torchvision im…

AI 数据采集实战指南:基于 Bright Data 快速获取招标讯息

AI 数据采集实战指南&#xff1a;基于Bright Data快速获取招标讯息 在招标行业中&#xff0c;快速、准确地获取招标公告、项目详情、投标截止日期和其他关键招标信息&#xff0c;是投标企业提高竞标成功率的核心竞争力。然而&#xff0c;招标信息往往分散在不同的平台和网页&a…

TCP 三次握手,第一次握手报文丢失会发生什么?

文章目录 RTO(Retransmission Timeout)注意 客户端想与服务端建立 TCP 连接时&#xff0c;先发送 SYN 报文&#xff0c;在这之后&#xff0c;如果客户端迟迟收不到服务端的 SYNACK 报文&#xff0c;就会触发「超时重传」机制&#xff0c;重新发送 SYN 报文&#xff0c;而且重传…

【DeepSeek论文精读】12. DeepSeek-Prover-V2: 通过强化学习实现子目标分解的形式化数学推理

欢迎关注[【AIGC论文精读】](https://blog.csdn.net/youcans/category_12321605.html&#xff09;原创作品 【DeepSeek论文精读】1. 从 DeepSeek LLM 到 DeepSeek R1 【DeepSeek论文精读】10. DeepSeek-Coder-V2: 突破闭源模型在代码智能领域的障碍 【DeepSeek论文精读】12. De…

第十一节:第一部分:正则表达式:应用案例、爬取信息、搜索替换

正则表达式介绍 String提供的正则表达式的方法的书写规则 正则表达式总结 正则表达式作用&#xff1a; 作用三&#xff1a;搜索替换 案例分析及代码&#xff08;图片解析&#xff09; 代码&#xff1a; 代码一&#xff1a;校验手机号和邮箱格式是否正确 package com.itheima.…

视频监控汇聚平台EasyCVR工业与安全监控:防爆摄像机的安全应用与注意事项

石油、化工、煤矿等行业存在易燃易爆气体、粉尘&#xff0c;普通监控设备易因电火花、高温引发爆炸火灾。随着工业规模扩大&#xff0c;安全生产监控需求激增&#xff0c;防爆摄像机成为保障安全的关键。加之国家法规与行业标准对危险环境监控设备要求严格&#xff0c;规范其应…

重学计算机网络之命令整理

配置权限相关 1.用户执行模式&#xff1a;查看网络设备状态信息 2.特权执行模式&#xff1a;查看和修改网络设备的状态和控制信息 3.全局配置模式&#xff1a;对整个网络设备进行全局性参数配置 4.接口配置模式&#xff1a;对网络设备的接口进行配置 enable #进入特权执行模式…

数据结构与算法Day3:绪论第三节抽象数据类型、算法及其描述

各位亲爱的读者&#xff0c;大家好&#xff01;今天博主给大家带来的内容是C语言数据结构与算法当中抽象数据类型、算法及其分析的相关知识。 一.抽象数据类型 抽象数据类型&#xff1a;指的是用户进行软件系统设计时从问题的数据模型中抽象出来的逻辑数据结构和逻辑数据结构上…

ABC 350

E. Toward 0 从大规模向小规模&#xff0c;用记忆化搜索&#xff0c;只需要分好类&#xff0c;有哪几种搜法。 期望实际上就是把每一种情况的答案答案都算出来&#xff0c;然后取个平均值 &#xff0c;并不困难。 f ( i ) [ f ( i / 6 ) f ( i / 5 ) f ( i / 4 ) f ( i / 3…

多相电机驱动控制学习(1)——基于双dq坐标系的六相/双三相PMSM驱动控制

1.引言 最近想学习一下多相电机。想从相对简单的开始吧&#xff0c;先学一个基于双dq的六相/双三相PMSM驱动控制&#xff08;考虑中性点隔离以及不隔离的情况&#xff0c;即考虑是否有零序电流回路&#xff09;&#xff0c;后面有时间再学学基于VSD的六相/双三相PMSM驱动控制。…

笔记: 在WPF中ContentElement 和 UIElement 的主要区别

一、目的&#xff1a;简要姐扫在WPF中ContentElement 和 UIElement 的主要区别 ContentElement 和 UIElement 是 WPF 中的两个基类&#xff0c;它们在功能和用途上有显著的区别。 二、主要区别 ContentElement 主要特点: • 没有视觉表示: ContentElement 本身不直接渲染任…