Проблема Aggregate/Annotate с OuterRef не работает с отношениями без FK в Django? Требуется ли FK?

У меня проблема с парой моделей из разных "общих приложений", которые у меня есть. Я не могу соединить их вместе, потому что эти приложения существуют в нескольких проектах (некоторые друг без друга), поэтому это нарушит другие проекты.

Это неуправляемая модель из appA - которая использует другую базу данных, которую мы будем называть databaseA для этого примера; в идеальном мире 'location_id' был бы FK, но, как я описал выше, это невозможно.

class Enrollment(models.Model):
    id = models.IntegerField(db_column="ID", primary_key=True)
    location_id = models.IntegerField(db_column="locationID")
    grade = models.CharField(db_column="grade", max_length=10)
    student_count = models.IntegerField(db_column="studentCount")
 
    class Meta(object):
        managed = False
        db_table = "mytable_Enrollments"

Это управляемая модель из appB, которая использует databaseB (которая является основной базой данных, используемой остальными приложениями в этом проекте); 'pk' или 'id' этой модели - это то, что указано в модели Enrollment в разделе location_id

class Location(models.Model):
    name = models.CharField(max_length=50)
    alternate_name = models.IntegerField()

Если я хочу получить Enrollment объекты для Location, я должен явно подставить число для идентификатора, как например:

location = Location.objects.get(id=1)
enrollments = Enrollment.objects.filter(location_id = location.id)

Но я пытаюсь аннотировать 'total_student_count' на модель Location следующим образом:

enrollments = (
    Enrollment.objects.filter(location_id=OuterRef("pk"))
    .order_by()
    .values("location_id")
)
total_enrollments = enrollments.annotate(
    total_student_count=Sum("student_count")
).values("total_student_count")
locations = (
    Location.objects.all()
    .order_by()
    .annotate(
        total_enrollments=Subquery(total_enrollments),
    )
)

Я сделал это аналогично примерам из документации .

Однако это просто возвращает total_enrollments: None в Queryset.

Если я заменяю OuterRef("pk") на целое число, например, 1 или 2 - переменная enrollments возвращает мне то, что я ожидал. Но использование OuterRef, кажется, ломается - и я не уверен почему.

Должен ли он быть FK? Из всего, что я нашел в Интернете, это не обязательно. Но я никак не могу найти способ заставить это работать.

У кого-нибудь есть идеи?

Вы можете попробовать что-то вроде следующего запроса

from django.db.models import Sum, F, Window

results = Enrollment.objects.filter(
    location_id__in=[location_ids]
).values(
    'location_id'
).distinct().annotate(
    total_student_count=Window(
        expression=Sum("student_count"), partition_by=[F("location_id")],
    )
).order_by('total_student_count')

Это отфильтрует зачисленных на основе предоставленных идентификаторов местоположения и даст общее количество зачисленных на основе каждого идентификатора местоположения

Вернуться на верх