title: 掌握Tortoise-ORM高级异步查询技巧

date: 2025/04/22 12:05:33

updated: 2025/04/22 12:05:33

author: cmdragon

excerpt:

Tortoise-ORM 提供了强大的异步查询功能,支持通过 Q 对象构建复杂查询条件,如逻辑运算符组合和动态条件构建。F 表达式用于字段级别的原子操作,避免竞争条件,适用于库存扣减和价格调整等场景。组合查询可通过注解和过滤实现复杂业务需求。常见错误包括字段不一致、未知字段和事务管理问题,需通过数据库迁移和异步上下文管理解决。

categories:

  • 后端开发
  • FastAPI

tags:

  • Tortoise-ORM
  • 异步查询
  • Q对象
  • F表达式
  • 数据模型
  • 复杂查询
  • 错误处理


扫描二维码关注或者微信搜一搜:编程智域 前端至全栈交流与成长

探索数千个预构建的 AI 应用,开启你的下一个伟大创意

以下是根据要求撰写的技术博客内容:


使用Tortoise-ORM实现高级异步查询

1. 环境准备

pip install fastapi uvicorn tortoise-orm pydantic

2. 数据模型定义

from tortoise.models import Model
from tortoise import fields class Product(Model):
id = fields.IntField(pk=True)
name = fields.CharField(max_length=255)
price = fields.DecimalField(max_digits=10, decimal_places=2)
stock = fields.IntField(default=0)
is_active = fields.BooleanField(default=True) class PydanticProduct(pydantic.BaseModel):
name: str
price: float
stock: int class Config:
orm_mode = True

3. Q对象深度解析

Q对象是构建复杂查询条件的利器,支持逻辑运算符组合查询条件

3.1 基础查询

# 查询价格大于100且库存充足的商品
products = await Product.filter(
Q(price__gt=100) & Q(stock__gte=10)
)

3.2 复杂逻辑组合

from tortoise.expressions import Q

# 查询(价格低于50或库存为0)且未下架的商品
query = Q(
(Q(price__lt=50) | Q(stock=0)) &
Q(is_active=True)
)
results = await Product.filter(query)

3.3 动态条件构建

def build_search_query(name: str = None, min_price: float = None):
query = Q()
if name:
query &= Q(name__icontains=name)
if min_price:
query &= Q(price__gte=min_price)
return query

4. F表达式实战应用

F表达式用于字段级别的原子操作,避免竞争条件

4.1 库存扣减

from tortoise.expressions import F

# 安全扣除库存
await Product.filter(id=product_id).update(
stock=F('stock') - quantity
)

4.2 价格调整

# 所有商品涨价10%
await Product.all().update(
price=F('price') * 1.1
)

4.3 字段比较查询

# 查找库存大于订购量的商品
await Product.filter(stock__gt=F('min_order_quantity'))

5. 组合查询示例

# 查询热门商品:评分>4且(价格<100或销量>1000)
hot_products = await Product.annotate(
total_sales=Sum('order_items__quantity')
).filter(
Q(rating__gt=4) &
(Q(price__lt=100) | Q(total_sales__gt=1000))
).order_by('-total_sales')

6. 课后Quiz

问题1:以下查询有什么问题?

await Product.filter(Q(name=user_input) | Q(description=user_input))

答案:存在SQL注入风险,应当使用参数化查询。Tortoise-ORM会自动处理参数绑定,但需要确保user_input来自可信来源或经过验证

问题2:如何原子性地实现"查看次数+1"?

答案:使用F表达式

await Product.filter(id=item_id).update(view_count=F('view_count') + 1)

7. 常见错误处理

错误1:OperationalError: no such column

原因:模型字段与数据库表结构不一致

解决

  1. 运行数据库迁移
aerich
upgrade
  1. 检查模型定义是否缺少字段

错误2:FieldError: Unknown field

原因:查询使用了不存在的字段名

解决

  1. 检查模型字段拼写
  2. 确认关联查询的related_name是否正确

错误3:TransactionManagementError

原因:在事务外执行需要事务的操作

解决

async with in_transaction():
await Product.update(...)

通过本文的代码示例和原理讲解,读者可以掌握Tortoise-ORM的高级查询技巧。建议在开发过程中结合API文档使用这些功能,并注意异步上下文管理。

余下文章内容请点击跳转至 个人博客页面 或者 扫码关注或者微信搜一搜:编程智域 前端至全栈交流与成长,阅读完整的文章:掌握Tortoise-ORM高级异步查询技巧 | cmdragon's Blog

往期文章归档:

掌握Tortoise-ORM高级异步查询技巧的更多相关文章

  1. SQL高级查询技巧

    SQL高级查询技巧   1.UNION,EXCEPT,INTERSECT运算符 A,UNION 运算符 UNION 运算符通过组合其他两个结果表(例如 TABLE1 和 TABLE2)并消去表中任何重 ...

  2. 二 配置数据字典&异步查询客户

    数据字典: 字典表和客户表的关系 配置字典表 配置客户表 Spring管理映射文件 1 字典表和客户表的关系 2 配置字典表 3  配置客户表 4  Spring管理映射文件 异步查询客户: 页面加载 ...

  3. js异步编程技巧一

    异步回调是js的一大特性,理解好用好这个特性可以写出很高质量的代码.分享一些实际用的一些异步编程技巧. 1.我们有些应用环境是需要等待两个http请求或IO操作返回后进行后续逻辑的处理.而这种情况使用 ...

  4. 《Entity Framework 6 Recipes》中文翻译系列 (11) -----第三章 查询之异步查询

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 第三章 查询 前一章,我们展示了常见数据库场景的建模方式,本章将向你展示如何查询实体 ...

  5. 《Entity Framework 6 Recipes》中文翻译系列 (41) ------ 第七章 使用对象服务之标识关系中使用依赖实体与异步查询保存

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 7-7  标识关系中使用依赖实体 问题 你想在标识关系中插入,更新和删除一个依赖实体 ...

  6. 关系数据库SQL之高级数据查询:去重复、组合查询、连接查询、虚拟表

    前言 接上一篇关系数据库SQL之基本数据查询:子查询.分组查询.模糊查询,主要是关系型数据库基本数据查询.包括子查询.分组查询.聚合函数查询.模糊查询,本文是介绍一下关系型数据库几种高级数据查询SQL ...

  7. MSSQL数据库链接字符串Asynchronous Processing=true不是异步查询吗,怎么是缓存

    ;Asynchronous Processing=true  不是异步查询吗,怎么是缓存 <!--<add name="default" providerName=&q ...

  8. php中mysql数据库异步查询实现

    问题 通常一个web应用的性能瓶颈在数据库.因为,通常情况下php中mysql查询是串行的.也就是说,如果指定两条sql语句时,第二条sql语句会等到第一条sql语句执行完毕再去执行.这个时候,如果执 ...

  9. asp.net mvc异步查询

    对于asp.net mvc异步查询 如何做MVC异步查询,做列表页面. 查询是项目中必不可少的工作,而且不同的项目不同的团队,都有自己的简单方法.Asp.net mvc 有自己独特的优势,下面是结合m ...

  10. Oracle-3 - :超级适合初学者的入门级笔记--用户权限,set运算符,高级子查询

    上一篇的内容在这里第二篇内容, 用户权限:创建用户,创建角色,使用grant  和 revoke 语句赋予和回收权限,创建数据库联接 创建用户:create user xxx identified b ...

随机推荐

  1. 从整理扑克牌到字母异位词分组:一道巧妙的排序应用题 |LeetCode 49 字母异位词分组

    LeetCode 49 字母异位词分组 点此看全部题解 LeetCode必刷100题:一份来自面试官的算法地图(题解持续更新中) 生活中的算法 你有没有玩过扑克牌?打完一局之后,我们通常会把散落的牌收 ...

  2. Centos7下oracle12c的安装与配置

    一.硬件资源配置(虚拟机) CentOS7@VMware Workstation 10 Pro,分配资源:CPU:2颗,内存:4GB,硬盘空间:20GB+30GB 二.软件环境配置 软件上传 xshe ...

  3. 埋点-App层丢失率

    一.建表语句 create table dws_bhv_habo_measure_lostrate_mb_di( version_flag bigint comment '版本标签 2:web丢失 3 ...

  4. mac 安装vue

    1.git clone https://github.com/vuejs/vue-devtools.git 切换master分支 cd vue-devtools npm install --regis ...

  5. C盘扩展卷碰到的那些事-->不是同一块物理磁盘操作扩展卷是有坑的

    自己电脑上面用过win10系统资源管理器扩展卷的功能,用过几次都成功扩容了磁盘空间,简单说一下原理: 就是将剩余未分配的磁盘空间划给要扩展的磁盘. 这天公司的电脑C盘老是红色提示空间不足,那就扩充容量 ...

  6. initiator 连接target

    客户端     检查是否发现 [root@kvm1 ~]# iscsiadm --mode discovery --type sendtargets --portal 192.168.114.14 1 ...

  7. C++最基本调用静态库的方法小结

    同样是最基本的调用方法小例,希望能带来参考,感谢! 创建静态库 编辑头文件 myLib.h: #pragma once #include "stdafx.h" int add(in ...

  8. 值得推荐的IT公司名单(成都篇)

    成都,作为新一线城市中的科技强市,拥有众多优秀的 IT 公司,为广大 IT 从业者提供了丰富的就业机会和良好的职业发展环境.以下是一些值得推荐的 IT 公司(排名不分先后): 一.互联网巨头在成都 1 ...

  9. C# 将list进行随机排序

    private List<T> RandomSortList<T>(List<T> ListT) { Random random = new Random(); L ...

  10. 移动端 cordova vue videojs 全屏播放后退出全屏返回后退出app问题

    问题描述 移动端上面使用了videojs 播放视频,同时也监听了手机返回事件document.addEventListener('backbutton',.接着我们点击全屏播放后在退出全屏在返回后直接 ...