我正在编写一个Django应用程序,用于查询Bugzilla数据库以进行报告。我正在尝试构建一个查询,可以获取所有设置了特定标志的错误。
表示标志表的模型。
class Bugzilla_flags(models.Model):
class Meta:
db_table = 'flags'
type_id = models.IntegerField()
status = models.CharField(max_length=50)
bug_id = models.IntegerField()
creation_date = models.DateTimeField()
modification_date = models.DateTimeField()
setter_id = models.IntegerField()
requestee_id = models.IntegerField()
def __unicode__(self):
return str(self.bug_id)
我有一个代表我想要查找的标志的字典(type_id:status)。
flags = {'36':'?','12':'+'}
我尝试使用reduce函数,但我认为它不会起作用,因为我正在检查所有标志是否存在于同一行中。如果我使用只有一个k,v对的字典运行查询,它可以正常工作,但不能超过1。
query = reduce(operator.and_, (Q(type_id=flag,status=val) for (flag,val) in flags.items()))
然后我将获取该查询的结果,并将其用作搜索实际错误数据库。
inner = Bugzilla_flags.objects.using('bugzilla').filter(query)
bugs = Bugzilla_bugs.objects.using('bugzilla').filter(bug_id__in=inner)
对于某些历史记录,我目前正在使用一系列步骤来生成一些我作为原始查询发送的sql,但我试图看看我是否可以在Django中执行此操作。生成的sql是这样的:
select b.bug_id, b.priority, b.bug_severity, b.bug_status, b.resolution, b.cf_verified_in, b.assigned_to, b.qa_contact, b.short_desc, b.cf_customercase,
MAX(CASE WHEN f.type_id = 31 THEN f.status ELSE NULL END) as Unlocksbranch1,
MAX(CASE WHEN f.type_id = 31 THEN f.status ELSE NULL END) as Unlocksbranch2,
MAX(CASE WHEN f.type_id = 33 THEN f.status ELSE NULL END) as Unlocksbranch3,
MAX(CASE WHEN f.type_id = 34 THEN f.status ELSE NULL END) as Unlocksbranch4,
MAX(CA5E WHEN f.type_id = 36 THEN f.status ELSE NULL END) as Unlocksbranch5,
MAX(CASE WHEN f.type_id = 41 THEN f.status ELSE NULL END) as Unlocksbranch6,
MAX(CASE WHEN f.type_id = 12 THEN f.status ELSE NULL END) as CodeReviewed
from bugs b
inner join flags f on f.bug_id = b.bug_id
where ( b.bug_status = 'RESOLVED' or b.bug_status = 'VERIFIED' or b.bug_status = 'CLOSED' )
and b.resolution = 'FIXED'
group by b.bug_id
having CodeReviewed = '+' and Unlocksbranch1 = '?' and Unlocksbranch2 = '+'
这样的结果给了我一个查询集,它包含我关心的所有标志作为列,然后我可以对其进行分析。最后一个“拥有”部分是我实际查询的内容,也是我想用上面的Django查询得到的内容。
修改
基本上我需要做的就是这样:
flags1 = {'36':'?'}
flags2 = {'12':'+'}
query1 = reduce(operator.and_, (Q(type_id=flag,status=val) for (flag,val) in flags1.items()))
query2 = reduce(operator.and_, (Q(type_id=flag,status=val) for (flag,val) in flags2.items()))
inner1 = Bugzilla_flags.objects.using('bugzilla').filter(query1)
inner2 = Bugzilla_flags.objects.using('bugzilla').filter(query2)
inner1_bugs = [row.bug_id for row in inner1] # list of just the bug_ids
inner2_bugs = [row.bug_id for row in inner2] # list of just the bug_ids
intersect = set(inner1_bugs) & set(inner2_bugs)
相交是一个包含所有bug_ids的集合,然后我可以在Bugzilla_bugs查询中使用它来获取实际的错误数据。
如何使用可变长度字典输入执行3个操作(query,inner,inner_bugs)然后交叉,例如:
flags = {'36':'?','12':'+','15','?',etc}
答案 0 :(得分:0)
您的inner
查询对我来说是正确的。要查找包含所有这些标记的错误,而不仅仅是任何标记,您可以再次使用reduce
与and
一起flag=
Q
个对象,或者迭代和构建多个过滤条款。
inner = Bugzilla_flags.objects.using('bugzilla').filter(query)
flag_filter = reduce(operator.and_, (Q(flag=flag) for flag in inner))
bugs = Bugzilla_bugs.objects.using('bugzilla').filter(flag_filter)
或者:
inner = Bugzilla_flags.objects.using('bugzilla').filter(query)
bugs = Bugzilla_bugs.objects.using('bugzilla').all()
for flag in inner:
bugs = bugs.filter(flag=flag)
或者,就此而言,利用多个Q
对象and
编辑在一起的事实:
inner = Bugzilla_flags.objects.using('bugzilla').filter(query)
flag_filters = [Q(flag=flag) for flag in inner]
bugs = Bugzilla_bugs.objects.using('bugzilla').filter(*flag_filters)