tortoise-orm annotate 使用
时间: 2025-03-31 07:13:36 浏览: 47
### Tortoise-ORM 中 `annotate` 方法的使用
在 Tortoise-ORM 中,`annotate` 是一种用于聚合数据的方法。它允许开发者通过 SQL 聚合函数(如 COUNT、SUM、AVG 等)来增强查询功能[^3]。
以下是关于如何在 Tortoise-ORM 中使用 `annotate` 进行查询的具体说明:
#### 基本语法
`annotate` 可以附加到查询链上,并接受键值对作为参数。其中键表示字段名称,而值是一个聚合表达式对象。这些表达式通常来自 Tortoise-ORM 提供的标准聚合类,例如 `Count`, `Sum`, 或者自定义的原始 SQL 表达式。
```python
from tortoise.models import Model
from tortoise.fields import IntField, ForeignKeyField
from tortoise.expressions import F
from tortoise.functions import Count, Sum
class Author(Model):
id = IntField(pk=True)
class Book(Model):
author: ForeignKeyRelation[Author] = ForeignKeyField('models.Author', related_name='books')
```
上述代码片段展示了两个模型之间的关系:`Book` 属于某个 `Author` 并且具有外键关联[^2]。
---
#### 示例 1:统计每位作者拥有的书籍数量
如果要计算每名作者对应的书籍总数,则可以利用 `annotate` 配合 `Count` 函数实现如下操作:
```python
authors_with_book_count = (
await Author.annotate(book_count=Count("books"))
.all()
)
for author in authors_with_book_count:
print(f"Author ID {author.id} has {author.book_count} books.")
```
此代码中的核心部分在于调用了 `annotate` 方法并传入了一个名为 `book_count` 的新属性,该属性由 `Count("books")` 计算得出。最终返回的结果集包含了原表的所有列以及新增加的 `book_count` 列[^3]。
---
#### 示例 2:按条件过滤后的统计数据
假设我们只关心那些至少有一本书被标记为畅销书的情况,可以通过组合 `filter` 和 `annotate` 来完成更复杂的逻辑处理:
```python
popular_books = (
await Book.filter(is_popular=True)
.values("author_id", "id")
)
annotated_authors = (
await Author.annotate(popular_book_count=Count("books__id", _filter=F("books__is_popular")))
.filter(popular_book_count__gt=0)
.all()
)
for author in annotated_authors:
print(f"Author with popular books count is {author.popular_book_count}.")
```
这里的关键点是在 `Count` 函数内部加入了 `_filter` 参数,从而实现了基于子条件的数据筛选[^4]。
---
#### 性能优化注意事项
当执行涉及大量记录或者复杂联结的操作时,请注意以下几点:
1. **减少不必要的字段加载**:尽可能使用 `.only()` 或 `.values()` 明确指定需要读取哪些字段。
2. **合理设置索引**:对于频繁参与分组或计数运算的列应建立适当数据库索引来提升效率。
3. **避免过度嵌套查询**:尽量简化查询结构以降低服务器负担。
---
### 结论
综上所述,在 Tortoise-ORM 中运用 `annotate` 方法能够极大地扩展基础 CRUD 功能之外的能力范围,使得应用程序具备更强的数据分析能力[^5]。
阅读全文
相关推荐


















