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
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/82683.shtml
英文地址,請注明出處:http://en.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 本身不直接渲染任…