查询一个字段,根据其他字段的排序获取“之后”匹配列表

时间:2012-01-26 11:03:07

标签: django

说我有下表,用于从客户端获取增量更新列表。当创建,修改或删除文章记录时,会在下表中添加一行。

id | article_id | uuid
---|------------|-------------------------------------
 1 |         56 | 78b69fa0-480b-11e1-b86c-0800200c9a66
 2 |         23 | 87c4fe60-480b-11e1-b86c-0800200c9a66
 3 |         78 | 903973f0-480b-11e1-b86c-0800200c9a66
 4 |         23 | bb3972d0-480b-11e1-b86c-0800200c9a66
 5 |         28 | f05fdd00-480b-11e1-b86c-0800200c9a66

客户端会记住上次同步中的uuid,并在下一个请求中包含此内容。假设客户已经知道上面的更改1和2;然后他会在请求中包含uuid 87c4fe60-480b-11e1-b86c-0800200c9a66(id = 2)。现在,我需要返回3-5行。如果来自客户端的uuid不在表中,则应该引发错误。

对此的简单蛮力方法是首先基于uuid进行搜索,然后使用找到的更改记录的id(在这种情况下为id = 2)到id为>的搜索。 “found_id”(在这种情况下,id> 2)。

有没有更有效的方式来查询这个,即以某种方式表达'在这个uuid之后给我所有行,其中行按id递增排序'?

2 个答案:

答案 0 :(得分:2)

你可以让Django在单个数据库命中中执行它,虽然它仍然是一个查询+子查询,如下所示:

MyModel.objects.filter(id__gt=MyModel.objects.filter(
     uuid='whatever').values_list('id',))

答案 1 :(得分:0)

您可以使用Django的extra()方法并在 where 子句中使用原始SQL。这将允许您在一个查询中选择所有文章。缺点是这是高度数据库引擎特定的。假设您的模型名为Article:

articles = Article.objects.extra(where=["id > (
    SELECT t2.id FROM "+Article._meta.db_table+" t2
    WHERE t2.uuid= '87c4fe60-480b-11e1-b86c-0800200c9a66'
    LIMIT 1)"]
).order_by('id').all())