【问题标题】:multiple joins on django querysetdjango 查询集上的多个连接
【发布时间】:2023-03-12 18:43:01
【问题描述】:

对于以下示例架构

    # schema sameple
    
    class A(models.Model):
        n = models.ForeignKey(N, on_delete=models.CASCADE)
        d = models.ForeignKey(D, on_delete=models.PROTECT)
    
    class N(models.Model):
        id = models.AutoField(primary_key=True, editable=False)
        d = models.ForeignKey(D, on_delete=models.PROTECT)
    
    class D(models.Model):
        dsid = models.CharField(max_length=255, primary_key=True)
    
    class P(models.Model):
        id = models.AutoField(primary_key=True, editable=False)
        name = models.CharField(max_length=255)
        n = models.ForeignKey(N, on_delete=models.CASCADE)
    
    # raw query for the result I want
    
    # SELECT P.name
    # FROM P, N, A
    # WHERE (P.n_id = N.id
    #     AND A.n_id = N.id
    #     AND A.d_id = \'MY_DSID\'
    #     AND P.name = \'MY_NAME\')

我想达到什么目的?

好吧,我正在尝试找到一种方法,能够以某种方式编写一个查询集,该查询集的功能与上述原始查询的功能相同。到目前为止,我能够通过编写两个查询集来做到这一点,并使用一个查询集的结果,然后使用我编写的第二个查询集来获取最终的数据库记录。然而,这对 DB 来说是 2 次命中,我想通过在一次 DB 命中中完成所有操作来优化它。

这种原始查询的查询集是什么?还是有更好的方法?

以上代码在这里https://dpaste.org/DZg2

【问题讨论】:

    标签: django postgresql django-models django-views django-queryset


    【解决方案1】:

    您可以使用related_name 属性和select_relatedprefetch_related 等函数对其进行归档。

    假设每个模型的相关名称将是模型的名称和_items,但最好有正确的模型名称,然后提供有意义的相关名称。相关名称是您反向访问模型的方式。

    这样,您可以使用此查询在单个数据库命中中获取所有模型:

    A.objects.all().select_related("n", "d", "n__d").prefetch_related("n__p_items")
    

    我编辑了pasted site中的代码,不过很快就会过期。

    【讨论】:

    • 感谢您的解决方案,但是,select_related 是一个查询,而 prefetch_related 是两个查询,所以前者更快。我想一击数据库。
    • 是的,Django 不支持在一个查询中选择超过 1 个表,它只能进行连接,并且 select_related 创建一个连接语句。除非您更改模型之间的关系,否则唯一的方法可能是使用 raw 函数并执行您自己的 SQL 代码。我不确定它的结果将如何解析,只需将其放入 django shell 并检查结果即可。
    • 这是另一个相关的问题:stackoverflow.com/questions/33224827/…
    • 我确实写了一个原始 SQL,并且在上面的问题中提到过,它可以工作。我想知道在 django QuerySet 中是否有一种方法可以利用,而不是使用 SQL 查询,这在可维护性方面不是最佳解决方案。 .
    • 不,在模型关系方面,如果与模型没有直接关系,Django ORM 不能一起查询它们。反向连接是使用预取功能的查询,它在辅助查询中完成。所以,Django ORM 没有办法在 SELECT 查询中有多个表,只能连接。
    猜你喜欢
    • 2016-08-20
    • 1970-01-01
    • 2016-06-12
    • 2013-06-26
    • 2020-07-17
    • 1970-01-01
    • 2018-02-08
    • 2021-01-21
    • 2018-03-06
    相关资源
    最近更新 更多