![cmdragon_cn.png image]()
扫描二维码关注或者微信搜一搜:编程智域 前端至全栈交流与成长
探索数千个预构建的 AI 应用,开启你的下一个伟大创意
以下是根据要求撰写的技术博客内容:
使用Tortoise-ORM实现高级异步查询
1. 环境准备
1
| pip install fastapi uvicorn tortoise-orm pydantic
|
2. 数据模型定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| 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 基础查询
1 2 3 4
| products = await Product.filter( Q(price__gt=100) & Q(stock__gte=10) )
|
3.2 复杂逻辑组合
1 2 3 4 5 6 7 8
| from tortoise.expressions import Q
query = Q( (Q(price__lt=50) | Q(stock=0)) & Q(is_active=True) ) results = await Product.filter(query)
|
3.3 动态条件构建
1 2 3 4 5 6 7
| 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 库存扣减
1 2 3 4 5 6
| from tortoise.expressions import F
await Product.filter(id=product_id).update( stock=F('stock') - quantity )
|
4.2 价格调整
1 2 3 4
| await Product.all().update( price=F('price') * 1.1 )
|
4.3 字段比较查询
1 2
| await Product.filter(stock__gt=F('min_order_quantity'))
|
5. 组合查询示例
1 2 3 4 5 6 7
| 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:以下查询有什么问题?
1
| await Product.filter(Q(name=user_input) | Q(description=user_input))
|
答案:存在SQL注入风险,应当使用参数化查询。Tortoise-ORM会自动处理参数绑定,但需要确保user_input来自可信来源或经过验证
问题2:如何原子性地实现”查看次数+1”?
答案:使用F表达式
:
1
| await Product.filter(id=item_id).update(view_count=F('view_count') + 1)
|
7. 常见错误处理
错误1:OperationalError: no such column
原因:模型字段与数据库表结构不一致
解决:
- 运行数据库迁移
- 检查模型定义是否缺少字段
错误2:FieldError: Unknown field
原因:查询使用了不存在的字段名
解决:
- 检查模型字段拼写
- 确认关联查询的related_name是否正确
错误3:TransactionManagementError
原因:在事务外执行需要事务的操作
解决:
1 2
| async with in_transaction(): await Product.update(...)
|
通过本文的代码示例和原理讲解,读者可以掌握Tortoise-ORM的高级查询技巧。建议在开发过程中结合API文档使用这些功能,并注意异步上下文管理。
余下文章内容请点击跳转至 个人博客页面 或者 扫码关注或者微信搜一搜:编程智域 前端至全栈交流与成长
,阅读完整的文章:
往期文章归档: