Django:选择具有最大时间戳的值或连接到同一个表

Nik*_*lub 4 python sql django postgresql

我有一个简单的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)
Run Code Online (Sandbox Code Playgroud)

我想将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;
Run Code Online (Sandbox Code Playgroud)

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

Rom*_*kar 7

如果你正在使用PostgreSQL,通常的语法是:

select distinct on (name)
    name, value
from environments_serverpropertie
where server = ...
order by name, timestamp desc
Run Code Online (Sandbox Code Playgroud)

PostgreSQL文档:

SELECT DISTINCT ON(expression [,...])仅保留给定表达式求值的每组行的第一行.使用与ORDER BY相同的规则解释DISTINCT ON表达式(参见上文).请注意,除非使用ORDER BY确保首先显示所需的行,否则每个集合的"第一行"都是不可预测的.

你可以看到并试一试sql fiddle demo.

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

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

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

ServerPropertie.objects.filter(...).order_by('name', '-timestamp').distinct('name')
Run Code Online (Sandbox Code Playgroud)