Django中的多连接查询

Posted

技术标签:

【中文标题】Django中的多连接查询【英文标题】:Multijoin queries in Django 【发布时间】:2008-09-16 14:00:53 【问题描述】:

在 Django 中使用 ORM 和 QuerySet API 进行多连接查询的最佳和/或最快方法是什么?

【问题讨论】:

【参考方案1】:

如果您尝试跨由 ForeignKeys 或 ManyToManyField 关系链接的表进行连接,则可以使用双下划线语法。例如,如果您有以下型号:

class Foo(models.Model):
    name = models.CharField(max_length=255)

class FizzBuzz(models.Model):
    bleh = models.CharField(max_length=255)

class Bar(models.Model):
    foo = models.ForeignKey(Foo)
    fizzbuzz = models.ForeignKey(FizzBuzz) 

你可以这样做:

Fizzbuzz.objects.filter(bar__foo__name = "Adrian")

【讨论】:

这不起作用:FieldError:无法将关键字“bar_set”解析为字段。选项有:bar、bleh、id 使用:Fizzbuzz.objects.filter(bar__foo__name = "Adrian") 自从我最初发布它以来,这可能在 1.5 年内发生了变化。感谢您的修复/更新!【参考方案2】:

不要使用 API ;-) 说真的,如果您的 JOIN 很复杂,您应该会看到通过使用 SQL 而不是使用 API 可以显着提高性能。这并不意味着您需要在漂亮的 Python 代码中使用肮脏的 SQL;只需创建一个自定义管理器来处理 JOIN,然后让其余代码使用它而不是直接使用 SQL。

另外,我刚刚参加了 DjangoCon,他们在那里举办了一个关于高性能 Django 的研讨会,我从中学到的关键内容之一是,如果性能是一个真正的问题(并且您计划有一天会有大量流量) ,你真的不应该首先做 JOIN,因为它们使你的应用在保持良好性能的同时扩展几乎是不可能的。

以下是 Google 制作的演讲视频: http://www.youtube.com/watch?v=D-4UN4MkSyI&feature=PlayList&p=D415FAF806EC47A1&index=20

当然,如果您知道您的应用程序永远不必处理这种扩展问题,请加入 :-) 如果您也不担心使用 API 对性能的影响,那么您真的不需要担心使用一种 API 方法与另一种 API 方法之间的(AFAIK)微小的性能差异(如果有的话)。

只需使用: http://docs.djangoproject.com/en/dev/topics/db/queries/#lookups-that-span-relationships

希望对您有所帮助(如果没有,希望一些真正的 Django 黑客可以介入并解释为什么方法 X 实际上确实有一些明显的性能差异)。

【讨论】:

“如果你的 JOIN 很复杂,你应该会看到通过使用 SQL 来显着提高性能”——这作为一个笼统的陈述是没有意义的。 ORM 在某些边缘情况下创建的 SQL 可能确实很差,但对于大多数 JOIN,它编写的 SQL 与您编写的 SQL 相同。【参考方案3】:

使用 queryset.query.join 方法,但前提是此处描述的其他方法(使用双下划线)不适用。

【讨论】:

【参考方案4】:

Caktus 博客对此有答案:http://www.caktusgroup.com/blog/2009/09/28/custom-joins-with-djangos-queryjoin/

基本上有一个隐藏的 QuerySet.query.join 方法允许添加自定义连接。

【讨论】:

以上是关于Django中的多连接查询的主要内容,如果未能解决你的问题,请参考以下文章

SQL数据库的多表查询

oracle中的多表查询和子查询以及一些注意事项

oracle的多表查询与表的连接

ORM的多表查询详述

Mysql中的关联查询(内连接,外连接,自连接)

Mysql中的关联查询(内连接,外连接,自连接)