Django альтернатива внутреннему присоединению при аннотировании
У меня возникли проблемы с генерацией аннотации для следующих моделей:
class ResultCode(GenericSteamDataModel):
id = models.IntegerField(db_column='PID')
result_code = models.IntegerField(db_column='resultcode', primary_key=True)
campaign = models.OneToOneField(SteamCampaign, db_column='campagnePID', on_delete=models.CASCADE)
sale = models.BooleanField(db_column='ishit')
factor = models.DecimalField(db_column='factor', max_digits=5, decimal_places=2)
class Meta:
managed = False
constraints = [
models.UniqueConstraint(fields=['result_code', 'campaign'], name='result_code per campaign unique')
]
class CallStatistics(GenericShardedDataModel, GenericSteamDataModel):
objects = CallStatisticsManager()
project = models.OneToOneField(SteamProject, primary_key=True, db_column='projectpid', on_delete=models.CASCADE)
result_code = models.ForeignKey(ResultCode, db_column='resultcode', on_delete=models.CASCADE)
class Meta:
managed = False
Цель - найти сумму факторов на основе поля result_code в модели ResultCode и CallStatistics, когда sale=True.
Обратите внимание на то, что: Коды результатов не являются уникальными сами по себе (описано в модели). Проект имеет отношение к Кампании
Следующая аннотация генерирует желаемый результат (возможное решение):
result = CallStatistics.objects.all().values('project').annotate(
sales_factored=models.Sum(
models.Case(
models.When(
models.Q(sale=True) & models.Q(project__campaign=models.F('result_code__campaign')),
then=models.F('result_code__factor')
)
)
)
)
Проблема заключается в том, что сгенерированный запрос выполняет Inner Join по result_code между 2 моделями. Пытаюсь добавить другое поле в ту же аннотацию (которое не должно соединяться с Resultcode), например:
sales=models.Sum(Cast('sale', models.IntegerField())),
приводит к неправильному суммированию.
Вопрос заключается в том, есть ли альтернатива автоматическому Inner Join, который генерирует Django. Чтобы можно было получить следующие поля (и другие подобные) в 1 аннотации:
...
sales=models.Sum(Cast('sale', models.IntegerField())),
sales_factored= [sum of factores, without Inner Join]
...
Заранее спасибо, что уделили этому время.