Я пишу приложение Django, которое запрашивает базу данных Bugzilla для отчетности. Я пытаюсь создать запрос, который может получить все ошибки, которые имеют определенные флаги.Django; как найти все ошибки, которые имеют определенные флаги
Модель, представляющая таблицу флагов.
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':'+'}
Я попытался с помощью функции уменьшения, но я не думаю, что это будет работать, потому что проверяет, что все флаги должны присутствовать в той же строке. Если я выполнить запрос со словарем с помощью всего одного к, 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 = '+'
В результате это дает мне один QuerySet, который имеет все флаги я забочусь о том, как колонны, которые я могу после этого сделать свой анализ на. Последний раздел «having» - это то, на что я действительно запрашиваю, и это то, что я пытаюсь получить с вышеуказанными запросами Django.
EDIT
В основном то, что мне нужно сделать, как это:
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 операции (запрос, внутренние, inner_bugs), а затем пересекаться с использованием словаря входной переменной длины, такие как:
flags = {'36':'?','12':'+','15','?',etc}
Ни одна из этих работ. Я всегда получаю нулевые строки, когда я делаю запрос Bugzilla_bugs с использованием фильтра. Я выяснил, как получить пересечение различных фильтров, но мне нужен чистый способ сделать это. Я редактировал вопрос. – zoidberg