对postgres的另一种查询'在Django中截然不同

时间:2018-03-15 01:41:45

标签: sql django postgresql django-models django-orm

鉴于这个django模型:

def Price(model.Model):
    date = models.DateTimeField()
    item = models.ForeignKey('Item', on_delete=models.CASCADE)
    price = models.IntegerField(blank=True, null=True)

目标是获得每个项目的最新价格,可以非常简单地查询..假设orm正在使用postgresql:

Price.objects.all().order_by('date').distinct('item')

使用其他数据库引擎时,不可能distinct on个特定字段,并且我想避免将自己锁定到postgres中,所以我一直在寻找一个查询模仿它。我写了/找到了一个完成这项工作的查询:

Price.objects.raw('''
    SELECT P1.*
    FROM `merchapi_pricelog` P1
        LEFT JOIN `merchapi_pricelog` P2
            ON P1.item_id = P2.item_id AND P1.date < P2.date
    WHERE P2.date is NULL
''')

原始查询比在代码中加载和过滤数据更快但我有兴趣看看是否有更好的方法以db-agnostic方式执行此操作,而不使用原始sql。< / p>

1 个答案:

答案 0 :(得分:1)

您可以使用子查询对其进行注释,因此可以在Item查询集中访问它。反之亦然,因为您似乎想要一个包含此数据的Price查询集,但这仍然可以为您服务:

latest_price = Price.objects.filter(pk=OuterRef('id')).order_by('-date').values('price')[:1]
items = Item.objects.annotate(latest_price=Subquery(latest_price))

我没有测试那个代码,只是从我在另一个项目中的类似内容中借用和修改,但相信它是准确的。

如果你需要迭代一个Price查询集,而不是一个Item查询集......我的大脑目前无法想到任何事情:)