python - 使用 select_lated 和 extra 子句

标签 python django

我正在尝试在查询集上实现一些额外的选择,并希望使用 select_lated 方法将所需的表添加到查询中的表池中,以便受益于“__”语法。

这是一个简单模型的示例:

from django.db import models

# Create your models here.

class testA(models.Model):
    code = models.TextField(unique = True)
    date = models.DateTimeField(auto_now_add = True)

class testB(models.Model):
    text = models.TextField()
    a = models.ForeignKey(testA)

这是我想要构建的查询:

SELECT (extract(hour from testa.date)) AS hour, testb.text FROM testb INNER JOIN testa ON (testb.a_id = testa.id)

这就是我如何在 python 中构建它:

testB.objects.all().select_related('a').extra(select = {'hour' : 'extract(hour from testa.date)'}).values('hour','text')

但是当 django 看到我没有使用“testa”表(因为“values”语句)时,他会删除 select_lated。因此生成的 SQL 查询失败:

SELECT (extract(hour from testa.date)) AS "hour", "testb"."text" FROM "testb"

如果我删除“值”语句,它就可以正常工作:

SELECT (extract(hour from testa.date)) AS "hour", "testb"."id", "testb"."text", "testb"."a_id", "testa"."id", "testa"."code", "testa"."date" FROM "testb" INNER JOIN "testa" ON ("testb"."a_id" = "testa"."id")

但是我必须放置值语句,因为我想要进行聚合,如“对按 a 对象中的日期小时分组的 b 对象进行计数”:

testB.objects.all().select_related('a').extra(select = {'hour' : 'extract(hour from testa.date)'}).values('hour').annotate(count = Count('pk'))

那么实现这一目标的好方法是什么? “计算由另一个对象中的某些内容分组的对象”?或者有没有办法“强制”django 保留“select_lated”表,即使他认为它们毫无用处?

PS:我知道我可以使用额外语句的“tables”参数,但在这种情况下,我必须自己重写连接,并且我想从 django ORM 中受益

最佳答案

我开发了一个 Django 应用程序来解决此类问题:django-cube 。基本思想是模拟多维数据库,以便轻松计算聚合。

您需要的功能(“__hour”:“hour”的字段查找)尚未实现,但实现它可能需要 15 分钟。因此,请阅读接下来的内容、它是如何工作的等等……如果它符合您的需求,请写信给我,我将实现它。

主页上的示例和 api 文档不是最新的(几天后就会更新),但是这些 snippets是。如果您想尝试一下,以下是使用 django-cube 解决此问题的方法:

#install the app first ...
from cube.models import Dimension, Cube

class MyCube(Cube):
    #declare a dimension called 'hour_a',
    #that is related to the field 'a__date__hour'.
    hour_a = Dimension(field='a__date__hour')

    #declare how to calculate the aggregation on a queryset
    @staticmethod
    def aggregation(queryset):
        return queryset.count()

然后,有多种方法可以计算结果,检查片段......例如,您可以使用:

cube(testB.objects.all()).measure_dict('hour_a', full=False)

这会返回类似的内容:

{   
    12: {measure: 889},
    13: {measure: 6654},
    14: {measure: 77},
    #<hour>: <count>
}

此外,不要采用特色下载,而是从源代码(分支 0.3)中 checkout 。

我不知道您的真正需求是什么,它对于您的使用可能有点繁重(它最初是为了数据可视化目的而制作的)。

关于python - 使用 select_lated 和 extra 子句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3280165/

相关文章:

python - Python多线程通信效率

python - 向装饰器添加参数

Python Flask 应用程序无法解析 XML 请求数据

python - 在 Django 模板中路由时,如何处理标题中的正斜杠 '/'?

python - 以可迭代作为参数的函数是否总是接受迭代器?

python - Flask 循环未按预期在 Bootstrap 下拉菜单中迭代

django/apache 无法在 Docker 容器中提供网页。错误 - ModuleNotFoundError : No module named 'django'

python - 如何从 django 模型获取 datetime.date() 值?

Django从查询集中填充form.ChoiceField字段,并将选择内容与模型对象相关联

django - 上传数据URL到Django服务器