【问题标题】:Avoid repeated select statement when using "extra" clause in Django ORM在 Django ORM 中使用“额外”子句时避免重复选择语句
【发布时间】:2015-03-18 15:16:54
【问题描述】:

我需要能够检索相关记录的总和以进行显示,并且还需要按三个相关模型的计数总和进行排序。目前,我正在通过使用“额外”子句来解决这个问题:

results = Poll.visible.extra(
    select={
        'f_count':
        """
        SELECT COUNT('id') FROM polls_forecast
        WHERE polls_forecast.poll_id = polls_poll.id
        """,
        'total':
        """
        (SELECT COUNT('id') FROM polls_forecast
         WHERE polls_forecast.poll_id = polls_poll.id) +
        (SELECT COUNT('id') FROM polls_pollcomment
         WHERE polls_pollcomment.poll_id = polls_poll.id) +
        (SELECT COUNT('id') FROM polls_favoritedpoll
         WHERE polls_favoritedpoll.poll_id = polls_poll.id)
        """
    }
).order_by('-total')[:100]

是否可以给f_count 加上别名,这样我就不必在total 选择语句中做同样的计数?在 total 选择中引用 f_count 会引发“列不存在”错误。

我正在使用 Postgres 9.4、Django 1.7.5、Python 3.4。

【问题讨论】:

    标签: django postgresql python-3.x


    【解决方案1】:

    不使用.extra。您需要使用raw。这是上面的docs

    如果您决定走这条路,您还必须在该原始 SQL 查询中执行visible 中涉及的过滤器。与 QuerySet 相比,我对 RawQuerySet 提供的功能不是 100% 肯定。

    【讨论】:

    • 我想了很多,我目前正在研究一个更有效的原始 sql 解决方案。一旦我的查询正常工作,我会发布我的答案,但接受你的答案,因为无法避免额外的查询。
    • 我想知道您是否可以将它们作为注释然后将它们加起来?所以Poll.visible.annotate(forecast_count=Count('forecast_set', distinct=True), etc, etc).extra(select={'total': 'sum(col1, col2)'})
    • 我决定暂时保留子查询。我最终会将此表格移至预定函数。
    猜你喜欢
    • 2016-06-12
    • 2012-03-15
    • 2017-02-09
    • 2013-04-19
    • 1970-01-01
    • 2020-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多