民间,
这是表T的模式(假设模型名称也是T,字段为A,B和C):
A B C
--- --- ---
1 a b
2 b NULL
3 c c
现在,我想选择值(A,C或B)。我可以按如下方式选择A和C:
T.objects.all().values_list('A','C')
但它只会给我A和C值。我想要的只是如果C是NULL,那么我应该得到B.我不知道我是否可以使用任何条件或加入直接实现这一点(对不起,我不是一个SQL人)但我绝对可以使用以下方法实现:
[(x,z or y) for (x,y,z) in T.objects.all().values_list('A','B','C')]
所以,有两个悬而未决的问题:
有没有更好的方式这样做? (最好使用Queryset / Django ORM函数)
如果有成千上万的记录,这样做的内存效率/优化方式是什么?除了使用循环(假设有序主键)将查询集限制为更小的块(假设一次说1000条记录)之外,还有其他方法,如下所示:
max_pkey = T.objects.all().order_by('-pk')[0] current = 0 chunk = 1000 while current <= max_pkey: objs = T.objects.filter(pk__gt=current)[:chunk] Process the objects
答案 0 :(得分:0)
在回答关于非常大的数据集的第二个问题时,您可能需要查看迭代器:
https://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.iterator
由于这不会在评估时尝试加载整个数据集,但显然存在权衡。
答案 1 :(得分:0)
我想我可以回答第一个问题。
1。有什么更好的方法吗? (最好使用Queryset / Django ORM函数)
Django提供了Conditional expressions,可让您执行此操作。
从Django文档中,
条件表达式使您可以使用if…elif…else过滤器,注释,聚合和更新中的逻辑。条件表达式为表的每一行评估一系列条件,并返回匹配的结果表达式。
对于您提供的架构,可以使用此:
T.objects.annotate(colA = F('A'),
colB_C = Case(When(C__isnull=True, then=F('B')),
default=F('C')))
对于每一行,如果C列中的值为null,则选择B列中的值。否则,将选择C列中的值。