聚合函数
目前支持 6 种聚合函数。
数数
count(distinct: bool = True) -> int
返回与给定条件匹配的行数(即应用过滤器和排除)。如果distinct为True(默认值),这将返回选定的主行数。如果为 False,则计数将是返回的总行数(包括一对多或多对多左 select_lated 表连接的额外行)。 False 是依赖于它的工作流的遗留(有缺陷的)行为。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 | class Book(ormar.Model):
ormar_config = ormar.OrmarConfig(
database=databases.Database(DATABASE_URL),
metadata=sqlalchemy.MetaData(),
tablename="book"
)
id: int = ormar.Integer(primary_key=True)
title: str = ormar.String(max_length=200)
author: str = ormar.String(max_length=100)
genre: str = ormar.String(
max_length=100,
default="Fiction",
choices=["Fiction", "Adventure", "Historic", "Fantasy"],
)
# returns count of rows in db for Books model
no_of_books = await Book.objects.count()
|
存在
存在() -> 布尔值
返回一个布尔值以确认是否有符合给定条件的行(与过滤器和排除一起应用)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 | class Book(ormar.Model):
ormar_config = ormar.OrmarConfig(
database=databases.Database(DATABASE_URL),
metadata=sqlalchemy.MetaData(),
tablename="book"
)
id: int = ormar.Integer(primary_key=True)
title: str = ormar.String(max_length=200)
author: str = ormar.String(max_length=100)
genre: str = ormar.String(
max_length=100,
default="Fiction",
choices=["Fiction", "Adventure", "Historic", "Fantasy"],
)
# returns a boolean value if given row exists
has_sample = await Book.objects.filter(title='Sample').exists()
|
和
总和(列)-> 任意
返回与给定条件匹配的行的列的总和值(应用过滤器,如果之前设置则排除)。
您可以传递一个或多个列名称,包括相关列。
截至目前,传递的每一列都是单独聚合的(因此 sum(col1+col2) 是不可能的,您可以使用 sum(col1, col2) ,然后在 python 中添加 2 个返回的总和)
您不能对非数字列求和。
如果对一列进行聚合,则直接返回单个值作为结果 如果对多列进行聚合,则返回包含 column: 结果对的字典
给定模型如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 | from typing import Optional
import databases
import ormar
import sqlalchemy
from tests.settings import DATABASE_URL
database = databases.Database(DATABASE_URL)
metadata = sqlalchemy.MetaData()
base_ormar_config = ormar.OrmarConfig(
metadata=metadata,
database=database,
)
class Author(ormar.Model):
ormar_config = base_ormar_config.copy(tablename="authors", order_by=["-name"])
id: int = ormar.Integer(primary_key=True)
name: str = ormar.String(max_length=100)
class Book(ormar.Model):
ormar_config = base_ormar_config.copy(
tablename="books", order_by=["year", "-ranking"]
)
id: int = ormar.Integer(primary_key=True)
author: Optional[Author] = ormar.ForeignKey(Author)
title: str = ormar.String(max_length=100)
year: int = ormar.Integer(nullable=True)
ranking: int = ormar.Integer(nullable=True)
|
示例用法可能如下所示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 | author = await Author(name="Author 1").save()
await Book(title="Book 1", year=1920, ranking=3, author=author).save()
await Book(title="Book 2", year=1930, ranking=1, author=author).save()
await Book(title="Book 3", year=1923, ranking=5, author=author).save()
assert await Book.objects.sum("year") == 5773
result = await Book.objects.sum(["year", "ranking"])
assert result == dict(year=5773, ranking=9)
try:
# cannot sum string column
await Book.objects.sum("title")
except ormar.QueryDefinitionError:
pass
assert await Author.objects.select_related("books").sum("books__year") == 5773
result = await Author.objects.select_related("books").sum(
["books__year", "books__ranking"]
)
assert result == dict(books__year=5773, books__ranking=9)
assert (
await Author.objects.select_related("books")
.filter(books__year__lt=1925)
.sum("books__year")
== 3843
)
|
平均
平均值(列)-> 任意
返回匹配给定条件的行的列的平均值(应用过滤器,如果之前设置则排除)。
您可以传递一个或多个列名称,包括相关列。
截至目前,传递的每一列都是单独聚合的(因此 sum(col1+col2) 是不可能的,您可以使用 sum(col1, col2) ,然后在 python 中添加 2 个返回的总和)
您不能对非数字列求平均值。
如果对一列进行聚合,则直接返回单个值作为结果 如果对多列进行聚合,则返回包含 column: 结果对的字典
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 | from typing import Optional
import databases
import ormar
import sqlalchemy
from tests.settings import DATABASE_URL
database = databases.Database(DATABASE_URL)
metadata = sqlalchemy.MetaData()
base_ormar_config = ormar.OrmarConfig(
metadata=metadata,
database=database,
)
class Author(ormar.Model):
ormar_config = base_ormar_config.copy(tablename="authors", order_by=["-name"])
id: int = ormar.Integer(primary_key=True)
name: str = ormar.String(max_length=100)
class Book(ormar.Model):
ormar_config = base_ormar_config.copy(
tablename="books", order_by=["year", "-ranking"]
)
id: int = ormar.Integer(primary_key=True)
author: Optional[Author] = ormar.ForeignKey(Author)
title: str = ormar.String(max_length=100)
year: int = ormar.Integer(nullable=True)
ranking: int = ormar.Integer(nullable=True)
|
示例用法可能如下所示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 | author = await Author(name="Author 1").save()
await Book(title="Book 1", year=1920, ranking=3, author=author).save()
await Book(title="Book 2", year=1930, ranking=1, author=author).save()
await Book(title="Book 3", year=1923, ranking=5, author=author).save()
assert round(float(await Book.objects.avg("year")), 2) == 1924.33
result = await Book.objects.avg(["year", "ranking"])
assert round(float(result.get("year")), 2) == 1924.33
assert result.get("ranking") == 3.0
try:
# cannot avg string column
await Book.objects.avg("title")
except ormar.QueryDefinitionError:
pass
result = await Author.objects.select_related("books").avg("books__year")
assert round(float(result), 2) == 1924.33
result = await Author.objects.select_related("books").avg(
["books__year", "books__ranking"]
)
assert round(float(result.get("books__year")), 2) == 1924.33
assert result.get("books__ranking") == 3.0
assert (
await Author.objects.select_related("books")
.filter(books__year__lt=1925)
.avg("books__year")
== 1921.5
)
|
分钟
分钟(列)-> 任意
返回匹配给定条件的行的列的最小值(与过滤器一起应用,如果之前设置则排除)。
您可以传递一个或多个列名称,包括相关列。
截至目前,传递的每一列都是单独聚合的(因此 sum(col1+col2) 是不可能的,您可以使用 sum(col1, col2) ,然后在 python 中添加 2 个返回的总和)
如果对一列进行聚合,则直接返回单个值作为结果 如果对多列进行聚合,则返回包含 column: 结果对的字典
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 | from typing import Optional
import databases
import ormar
import sqlalchemy
from tests.settings import DATABASE_URL
database = databases.Database(DATABASE_URL)
metadata = sqlalchemy.MetaData()
base_ormar_config = ormar.OrmarConfig(
metadata=metadata,
database=database,
)
class Author(ormar.Model):
ormar_config = base_ormar_config.copy(tablename="authors", order_by=["-name"])
id: int = ormar.Integer(primary_key=True)
name: str = ormar.String(max_length=100)
class Book(ormar.Model):
ormar_config = base_ormar_config.copy(
tablename="books", order_by=["year", "-ranking"]
)
id: int = ormar.Integer(primary_key=True)
author: Optional[Author] = ormar.ForeignKey(Author)
title: str = ormar.String(max_length=100)
year: int = ormar.Integer(nullable=True)
ranking: int = ormar.Integer(nullable=True)
|
示例用法可能如下所示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 | author = await Author(name="Author 1").save()
await Book(title="Book 1", year=1920, ranking=3, author=author).save()
await Book(title="Book 2", year=1930, ranking=1, author=author).save()
await Book(title="Book 3", year=1923, ranking=5, author=author).save()
assert await Book.objects.min("year") == 1920
result = await Book.objects.min(["year", "ranking"])
assert result == dict(year=1920, ranking=1)
assert await Book.objects.min("title") == "Book 1"
assert await Author.objects.select_related("books").min("books__year") == 1920
result = await Author.objects.select_related("books").min(
["books__year", "books__ranking"]
)
assert result == dict(books__year=1920, books__ranking=1)
assert (
await Author.objects.select_related("books")
.filter(books__year__gt=1925)
.min("books__year")
== 1930
)
|
最大限度
最大(列)-> 任意
返回匹配给定条件的行的列的最大值(与过滤器一起应用,如果之前设置则排除)。
返回匹配给定条件的行的列的最小值(与过滤器一起应用,如果之前设置则排除)。
您可以传递一个或多个列名称,包括相关列。
截至目前,传递的每一列都是单独聚合的(因此 sum(col1+col2) 是不可能的,您可以使用 sum(col1, col2) ,然后在 python 中添加 2 个返回的总和)
如果对一列进行聚合,则直接返回单个值作为结果 如果对多列进行聚合,则返回包含 column: 结果对的字典
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 | from typing import Optional
import databases
import ormar
import sqlalchemy
from tests.settings import DATABASE_URL
database = databases.Database(DATABASE_URL)
metadata = sqlalchemy.MetaData()
base_ormar_config = ormar.OrmarConfig(
metadata=metadata,
database=database,
)
class Author(ormar.Model):
ormar_config = base_ormar_config.copy(tablename="authors", order_by=["-name"])
id: int = ormar.Integer(primary_key=True)
name: str = ormar.String(max_length=100)
class Book(ormar.Model):
ormar_config = base_ormar_config.copy(
tablename="books", order_by=["year", "-ranking"]
)
id: int = ormar.Integer(primary_key=True)
author: Optional[Author] = ormar.ForeignKey(Author)
title: str = ormar.String(max_length=100)
year: int = ormar.Integer(nullable=True)
ranking: int = ormar.Integer(nullable=True)
|
示例用法可能如下所示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 | author = await Author(name="Author 1").save()
await Book(title="Book 1", year=1920, ranking=3, author=author).save()
await Book(title="Book 2", year=1930, ranking=1, author=author).save()
await Book(title="Book 3", year=1923, ranking=5, author=author).save()
assert await Book.objects.max("year") == 1930
result = await Book.objects.max(["year", "ranking"])
assert result == dict(year=1930, ranking=5)
assert await Book.objects.max("title") == "Book 3"
assert await Author.objects.select_related("books").max("books__year") == 1930
result = await Author.objects.select_related("books").max(
["books__year", "books__ranking"]
)
assert result == dict(books__year=1930, books__ranking=5)
assert (
await Author.objects.select_related("books")
.filter(books__year__lt=1925)
.max("books__year")
== 1923
)
|
QuerysetProxy 方法
当直接访问相关的ManyToMany字段以及ReverseForeignKey时,返回相关模型的列表。
但同时它公开了 QuerySet API 的子集,因此您可以直接从父模型过滤、创建、选择相关模型等。
数数
与上面的 count 函数完全相同,但允许您从关系另一端的相关对象中选择列。
!!!tip 要了解有关 QuerysetProxy 的更多信息,请访问 querysetproxy 部分
存在
与上面的存在函数完全相同,但允许您从关系另一端的相关对象中选择列。
和
与上面的 sum 函数完全相同,但允许您对关系另一端的相关对象的列进行求和。
平均
与上面的 avg 函数完全相同,但允许您对关系另一端的相关对象的列进行平均。
分钟
与上面的 min 函数完全相同,但允许您从关系另一端的相关对象中选择最少的列。
最大限度
与上面的 max 函数完全相同,但允许您从关系另一端的相关对象中选择最大列。
!!!tip 要了解有关 QuerysetProxy 的更多信息,请访问 querysetproxy 部分