Python Django ORM中的数据透视和复杂注释

Python Django ORM中的数据透视和复杂注释,python,sql,django,django-orm,Python,Sql,Django,Django Orm,Django中的ORM允许我们基于相关数据轻松地对查询集进行注释(向查询集添加字段),尽管我无法找到一种方法来为相关数据的不同过滤子集获取多个注释 这是一个与开源Django驱动的故障单跟踪器相关的问题。我需要像这样的数据透视图和报告的目的 以这些模型为例: CHOICE_LIST = ( ('open', 'Open'), ('closed', 'Closed'), ) class Queue(models.model): name = models.CharFiel

Django中的ORM允许我们基于相关数据轻松地对查询集进行注释(向查询集添加字段),尽管我无法找到一种方法来为相关数据的不同过滤子集获取多个注释

这是一个与开源Django驱动的故障单跟踪器相关的问题。我需要像这样的数据透视图和报告的目的

以这些模型为例:

CHOICE_LIST = (
    ('open', 'Open'),
    ('closed', 'Closed'),
)

class Queue(models.model):
    name = models.CharField(max_length=40)

class Issue(models.Model):
    subject = models.CharField(max_length=40)
    queue = models.ForeignKey(Queue)
    status = models.CharField(max_length=10, choices=CHOICE_LIST)
这个数据集:

队列:

ID | Name
---+------------------------------
1  | Product Information Requests
2  | Service Requests
ID | Queue | Status
---+-------+---------
1  | 1     | open
2  | 1     | open
3  | 1     | closed
4  | 2     | open
5  | 2     | closed
6  | 2     | closed
7  | 2     | closed
问题:

ID | Name
---+------------------------------
1  | Product Information Requests
2  | Service Requests
ID | Queue | Status
---+-------+---------
1  | 1     | open
2  | 1     | open
3  | 1     | closed
4  | 2     | open
5  | 2     | closed
6  | 2     | closed
7  | 2     | closed
我希望看到注释/聚合如下所示:

Queue ID | Name                          | open | closed
---------+-------------------------------+------+--------
1        | Product Information Requests  | 2    | 1
2        | Service Requests              | 1    | 3
用Excel的说法,这基本上是一个交叉表或数据透视表。我目前正在使用一些自定义SQL查询构建此输出,但是如果我可以使用Django ORM,我就可以更轻松地动态过滤数据,而无需在SQL中插入WHERE子句


对于“红利点数”:如果pivot字段(在上面的示例中为status)是一个日期,并且我们希望列是月/周/季度/天,那么如何实现这一点呢?

如果您有Python,请使用它

from collections import defaultdict
summary = defaultdict( int )
for issue in Issues.objects.all():
    summary[issue.queue, issue.status] += 1
现在,您的
摘要
对象具有队列,状态为两元组键。您可以使用各种模板技术直接显示它

或者,如果更简单的话,您可以将其重新组合成类似于表的结构

table = []
queues = list( q for q,_ in summary.keys() )
for q in sorted( queues ):
    table.append( q.id, q.name, summary.count(q,'open'), summary.count(q.'closed') )
您有很多Python技术来处理透视表


如果您进行测量,您可能会发现像这样一个以Python为主的解决方案实际上比一个纯SQL解决方案要快。为什么?映射可以比SQL算法更快,SQL算法需要排序作为分组依据的一部分。

自从最初提出这个问题以来,Django为ORM添加了很多功能。Django 1.8之后如何透视数据的答案是使用Case/When。还有一个第三方应用程序可以为您实现这一点,如果Issues table很大,并且很难被视为通用,那么这个解决方案就会崩溃。对于几年后阅读本文的人来说:我得到了
集合。defaultdict对象没有python3的属性“count”
summary.count(q.“closed”)
也做透视表。django-sql-explorer是一个很好的工具,透视表功能在这种情况下可能很有用,但最初的问题是如何在ORM中做透视表,而django-sql-explorer在ORM返回所有原始数据后用javascript做透视表。