基于模型字段限制查询集结果,是否有更好的方法?

2024-06-25 22:56:29 发布

您现在位置:Python中文网/ 问答频道 /正文

基本上我想得到每个主机的最新30个日志条目。目前我在django活塞做这个。在

def read(self,request):
    val={}
    for x in Host.objects.all():
        val[x.uuid_id]=DataLog.objects.filter(host=x).order_by('-time')[:30]           
    return val

不幸的是,这个请求的方式是long(对于大约10k个数据库条目,目前是1s)。 有没有更有效的方法?在

哈珀


Tags: djangoinselfidhostforreadobjects
1条回答
网友
1楼 · 发布于 2024-06-25 22:56:29

如果您使用PostgreSQL作为数据库后端,并且不需要跨数据库兼容性,则可以使用允许这样做的powerful window functions

想象一下你的桌子是这样的:

CREATE TABLE x (
    i serial primary key,
    value integer not null,
    date timestamp,
    category text);

您需要每个类别的最新值。您将:

^{pr2}$

可以通过查询集管理器上的raw方法在django中使用这样的查询:

ModelX.objects.raw("""SELECT DISTINCT ....... FROM x WINDOW w .....""")

要按类别获取最后N个条目,查询稍微复杂一些,并涉及一个子查询:

SELECT i, value, date, category
FROM (SELECT
        i, value, date, category,
        row_number() over w
    FROM x
    WINDOW w AS (PARTITION BY category ORDER BY date DESC)) AS subquery
WHERE subquery.row_number <= 30;

看到这一点,你甚至可以看到:

CREATE VIEW x_with_reverse_date_index AS
    (SELECT
        i, value, date, category,
        row_number() over w
    FROM x
    WINDOW w AS (PARTITION BY category ORDER BY date DESC));

并创建一个django模型来查询此视图:

class ModelX(models.Model):
    ...
    ...
    row_number = models.IntegerField("Row number when ordering by date desc")

    class Meta:
        db_table = 'x_with_reverse_date_index'

并“正常”查询:

ModelX.objects.filter(category__in = ('catA','catB'), row_number__lte = 30)
ModelX.objects.filter(row_number = 29)
...

警告:同样,如果需要在另一个数据库引擎上运行的代码,请不要这样做。在

相关问题 更多 >