5

我有一个简单的 Django 模型

class Server(models.Model):
    name = models.CharField(max_length=120)

class ServerPropertie(models.Model):
    name = models.CharField(max_length=120)
    value = models.CharField(max_length=120)
    timestamp = models.DateTimeField()
    server = models.ForeignKey(Server)

我想将 get_properties 方法添加到 Server 模型中,它将返回当前服务器的所有最后属性。我的意思是它应该返回当前服务器的所有属性名称的名称和值,并且每个 uniq 属性名称应该有一个值,该行具有最大时间戳。

我可以在原始硬编码的原始 SQL 中做到这一点(我使用 postgres):

SELECT t1.name, t1.value FROM environments_serverpropertie t1
JOIN (SELECT max("timestamp") "timestamp", name 
      FROM environments_serverpropertie
      group by name) t2 on t1.name = t2.name and t1.timestamp = t2.timestamp;

或在 python 中,但我相信存在 pythonic 解决方案。请你帮助我好吗。

4

1 回答 1

7

如果您使用的是 PostgreSQL,通常的语法是:

select distinct on (name)
    name, value
from environments_serverpropertie
where server = ...
order by name, timestamp desc

来自PostgreSQL 文档

SELECT DISTINCT ON ( expression [, ...] ) 只保留给定表达式计算结果为相等的每组行的第一行。DISTINCT ON 表达式使用与 ORDER BY 相同的规则进行解释(见上文)。请注意,除非使用 ORDER BY 确保所需的行首先出现,否则每组的“第一行”是不可预测的。

您可以在 中查看并尝试sql fiddle demo

可以从django 文档中将此语法翻译成 django :

仅在 PostgreSQL 上,您可以传递位置参数 (*fields) 以指定应应用 DISTINCT 的字段名称。这将转换为 SELECT DISTINCT ON SQL 查询。

所以在 django 中它会是这样的:

ServerPropertie.objects.filter(...).order_by('name', '-timestamp').distinct('name')
于 2013-08-25T20:36:12.283 回答