繁体   English   中英

Django查询ORM以基于主键进行查询,然后从由外键链接的联结表中获取信息

[英]Django query ORM to query based on primary key then get information from junction tables linked by foreign key

我有一个具有主键的表,我想在该主键上查询该表。 这链接到2个联结表,这些表是与我的第一个表链接的外键。 我可以从所有这些表中访问与该主键有关的所有信息:

models.py:

class Variant(models.Model):
    variant = models.CharField(max_length=60, primary_key=True)


class VarSamRun(models.Model:
    sample = models.ForeignKey(Sample, on_delete=models.CASCADE, db_column='sample')
    variant = models.ForeignKey(Variant, on_delete=models.CASCADE, db_column='variant')
    run = models.ForeignKey(Run, on_delete=models.CASCADE, db_column='run')
    .... 
    more attributes
    ...


class ClinVarSam(models.Model:
    sample = models.ForeignKey(Sample, on_delete=models.CASCADE, db_column='sample')
    variant = models.ForeignKey(Variant, on_delete=models.CASCADE, db_column='variant')
    .... 
    more attributes
    ...

我想使用一些变量来查询VarSamRun:

obj = VariantSampleRun.objects.filter(sample=sample, run=run).select_related('variant')

但我似乎无法从此对象从ClinVarSamRun获取任何信息

我也尝试过:

obj = Variant.objects.prefetch_related('variant__clinicallyreportedvariant_set', 'variantsamplerun_set')

但这又不包含任何VarSamRun或ClinVarSamRun对象属性

我怎样才能得到这些?

更新的答案

我根据您的评论想到了一种解决方案:

variants = Variant.objects.filter(variantsamplerun_set__sample=sample, variantsamplerun_set__run=run).values_list('variant', 'variantsamplerun_set__sample_id', 'clinvarsam_set__some_field', 'clinvarsam_set__other_field')
for v in variants:
    print(v['variant'], v['variantsamplerun_set__sample_id'], v['clinvarsam_set__some_field'], v['clinvarsam_set__other_field'])

我认为values_list方法可能会很好地实现您所追求的查询。 https://docs.djangoproject.com/en/1.11/ref/models/querysets/#values-list

旧答案

我认为您在误解select_related的用法,这将在您评估查询集时更改对数据库的查询,而不返回变体。 另外,您是说要使用.filter还是.get? .filter返回一个Queryset而不是一个对象。

varsamrun_qs = VariantSampleRun.objects.filter(sample=sample, run=run).select_related('variant')
for varsamrun in varsamrun_qs:
    print(varsamrun.variant)  # This does not make an extra sql call to retrieve the variant object

这应该使一个SQL查询来评估查询集并检索相关的变体字段,然后打印每个VariantSampleRun的变体。

如果您希望能够从匹配的VarSamRun中检索ClinVarSam,则可以将属性方法添加到VarSamRun模型中:

class VarSamRun(models.Model:
    sample = models.ForeignKey(Sample, on_delete=models.CASCADE, db_column='sample')
    variant = models.ForeignKey(Variant, on_delete=models.CASCADE, db_column='variant')
    run = models.ForeignKey(Run, on_delete=models.CASCADE, db_column='run')
    .... 
    more attributes
    ...

    @property
    def clinvarsam(self):
        return ClinVarSam.objects.get(sample=self.sample, variant=self.variant)

然后在之前的示例中使用它:

varsamrun_qs = VariantSampleRun.objects.filter(sample=sample, run=run).select_related('variant')
for varsamrun in varsamrun_qs:
    print(varsamrun.variant)  # This does not make an extra sql call to retrieve the variant object
    print(varsamrun.clinvarsam)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM