说我有下表,用于从客户端获取增量更新列表。当创建,修改或删除文章记录时,会在下表中添加一行。
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递增排序'?
答案 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())