Django фильтр в другой модели без внешнего ключа

У меня есть две разные модели:

class AggUii(Model):
    year = models.IntegerField(blank=True, null=True)
    month = models.CharField(max_length=2, blank=True, null=True)
    country = models.CharField(max_length=7, blank=True, null=True)
    service = models.CharField(max_length=16, blank=True, null=True)
    doc_id = models.CharField(max_length=100, blank=True, null=True)
    counts = models.IntegerField(blank=True, null=True)
    data_type = models.CharField(max_length=200, blank=True, null=True)
    section_type = models.CharField(max_length=200, blank=True, null=True)
    yop = models.CharField(db_column='YOP', max_length=4, blank=True, null=True)  # Field name made lowercase.

    class Meta:
        managed = False
        db_table = 'agg_uii'

class HierarchieIndexDocid(Model):
    ancestor = models.CharField(max_length=255)
    descendant_docid = models.CharField(max_length=255, blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'hierarchie_index_docid'

Как видите, эти таблицы не связаны между собой внешним ключом. Поле doc_id в AggUii Model не является уникальным. И все же приведенный ниже запрос Mysql работает, выдавая правильные результаты.

Можно ли как-то перестроить этот оператор MySQL в Django ORM? В качестве параметра передается meta_id.

SELECT agg_uii.year, SUM(agg_uii.counts) FROM agg_uii,hierarchie_index_doc_id WHERE (agg_uii.doc_id=hierarchie_index_doc_id.descendant_docid and hierarchie_index_docid.ancestor="meta_id") GROUP BY agg_uii.year;

Спасибо!

class AggUii(Model):
    # .
    doc_id = models.CharField(max_length=100, blank=True, null=True, unique=True)
    # .

    class Meta:
        managed = False
        db_table = 'agg_uii'


class HierarchieIndexDocid(Model):
    ancestor = models.CharField(max_length=255)
    descendant = models.ForeignKey(
        AggUii,
        to_field='doc_id',
        db_column='descendant_docid',
        blank=True,
        null=True,
        on_delete=models.PROTECT,
    )

    class Meta:
        managed = False
        db_table = 'hierarchie_index_docid'

Тогда мы можем запросить:

from django.db.models import Sum

AggUii.objects.filter(hierarchieindexdocid__ancestor='meta_id').values(
    'year'
).annotate(total=Sum('counts')).order_by('year')

Вот как я решил эту проблему:

from django.db.models import Q, Subquery

Я сделал следующий запрос:

doc_id_hier_qs = HierarchieIndexDocid.objects.filter(~Q(descendant_docid=""),ancestor=meta_id).values('descendant_docid')

После этого я использовал метод Subquery в Django:

invyearsqs_sq = AggUii.objects.force_index("idx_doc_id").filter(doc_id__in=Subquery(doc_id_hier_qs.values("descendant_docid"))).values('year').annotate(invSumYr = Sum('counts'))

Работает как шарм!

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