Django 2.1+ 批量更新记录及其相关记录的数量?

Sta*_*cat 3 python django postgresql

我正在尝试使用表 B 中相关记录的计数来批量更新表 A 中的所有记录。

我想做这样的事情:

from django.db.models import Subquery, OuterRef, Count


table_b_subquery = TableB.objects.filter(a_id=OuterRef('id'))

TableA.objects.all().update(table_b_count=Count(Subquery(table_b_subquery)))
Run Code Online (Sandbox Code Playgroud)

这相当于这种非批量方法:

# Non-Bulk

for record in TableA.objects.all():
  record.table_b_count = record.table_b_set.count()
Run Code Online (Sandbox Code Playgroud)

我尝试批量方法时遇到的错误是:

*** django.core.exceptions.FieldError: Aggregate functions are not allowed in this query
Run Code Online (Sandbox Code Playgroud)

如何在批量更新中对相关记录进行看似简单的计数?理想情况下,我也想对表 B 的计数应用一个简单的字段过滤器。

End*_*oth 6

您需要一个用于计数的子查询(而不仅仅是可数对象),这有点麻烦,因为常规聚合查询喜欢count()立即aggregate()执行,而子查询则需要惰性执行。这就是为什么annotate()需要下面的解决方法:

from django.db.models import Subquery, OuterRef, Count

table_b_subquery = Subquery(TableB.objects
    .filter(a_id=OuterRef('id'))
    .values('a_id')
    .annotate(cnt=Count('a_id'))
    .values('cnt')
)

TableA.objects.update(table_b_count=table_b_subquery)
Run Code Online (Sandbox Code Playgroud)