2012-08-24 10 views
8

Aşağıdaki kurulumda, her biri tüm görev sürelerinin (task_duration olarak) ve tüm görevlerinin toplamının toplamı ile açıklanmış bir proje listesi içeren bir QuerySet'i istiyorum. subtask süreleri (subtasks_duration olarak). (Basitleştirilmiş) Benim modelleri şu şekilde görünür: davranışa İlişkinmultiple annotate Toplam terim sayısı şişirilmiş yanıt verir

Projects.objects.annotate(tasks_duration=Sum('task__duration'), subtasks_duration=Sum('task__subtask__duration')) 

Django annotate() multiple times causes wrong answers açıklandığı ben olması gerektiği çok daha yüksek bir tasks_duration olsun:

class Project(models.Model): 
    pass 

class Task(models.Model): 
    project = models.ForeignKey(Project) 
    duration = models.IntegerField(blank=True, null=True) 

class SubTask(models.Model): 
    task = models.ForeignKey(Task) 
    duration = models.IntegerField(blank=True, null=True) 

Bu gibi benim QuerySet olun. Çoklu ek açıklama (Sum()) cümleleri, ortaya çıkan SQL'de çoklu sol iç birleştirmeler sağlar. Tasks_duration için sadece bir tek notla (Sum()) terimi ile sonuç doğrudur. Ancak, hem task_duration hem de subtasks_duration sahip olmak isterim.

Bu sorguyu yapmak için uygun bir yol ne olurdu? Proje başına düşen bir çalışma çözümüm var ama bu beklenmedik bir şekilde yavaş. Ekstra bir() çağrısı ile çalışan benzer bir şeyim var, ama istediğim şeyin saf Django ile mümkün olup olmadığını bilmek isterim.

+0

: Yani bir hile kullanmak ve bir ORM aşağıda gibi yazabilirsiniz bağlandığınız diğer soruda bahsedilen? – jpic

+0

Bu, yalnızca istediğim gibi olmayan belirli süre değerlerinin toplamına hizmet edecektir. Ben merak ettim, hala aynı yanlış değerleri verir. (süreler değişebilir) –

+0

Bunun için bir geçici çözüm buldunuz mu? Ben bir queryset üzerinde bir toplamı ve bir sayımı eklemeye çalışıyorum ve toplam tutar çoğalmaya devam ediyor ... – StephenTG

cevap

1

Bu hatayı da alıyorum. Tam olarak aynı kod. Birbirini ayrı ayrı yaparsam çalışır, ama aynı anda her iki değeri de almayı denediğimde, bir tanesi bir faktör 2 daha yüksek, diğeri ise bir faktör 3 olur.

Neden Django'nun böyle davrandığını bilmiyorum yol. Buraya bir hata raporu gönderdim: https://code.djangoproject.com/ticket/19011 Bunu takip etmek de ilginizi çekebilir.

+0

Django'da gerçekten bir hata değil, bu toplu sorguları veritabanına koymanın karmaşıklığı sorunu. SQL'i kendiniz yazmış olsanız bile, bu problemi çözmelisiniz. – benjaoming

+1

İlgili hata raporuna bağlantı: https://code.djangoproject.com/ticket/10060 – benjaoming

+0

Bu hata hala düzeltilmemiş. – sobolevn

1

Hata, here bildirilmiştir, ancak Django 1.11'de bile çözülmez. Sorun, ters ilişkilerde iki tabloya katılmakla ilgilidir. Ayrı parametrenin Say için değil, Toplam için iyi çalıştığına dikkat edin. Eğer olarak `` tasks_duration = Sum ('task__duration', farklı = True), subtasks_duration = Sum ('task__subtask__duration', farklı = True) denedin mi

Projects.objects.annotate(
     temp_tasks_duration=Sum('task__duration'), 
     temp_subtasks_duration=Sum('task__subtask__duration'), 
     tasks_count=Count('task'), 
     tasks_count_distinct=Count('task', distinct=True), 
     task_subtasks_count=Count('task__subtask'), 
     task_subtasks_count_distinct=Count('task__subtask', distinct=True), 
).annotate(
     tasks_duration=F('temp_tasks_duration')*F('tasks_count_distinct')/F('tasks_count'), 
     subtasks_duration=F('temp_subtasks_duration')*F('subtasks_count_distinct')/F('subtasks_count'), 
)