2009-07-12 11 views
0

Wie kann ich Datensätze mit mehreren Einschränkungen unter Verwendung der Aggregatfunktionalität von django zählen?Kann ich mit django aggregate functionlity auf mehrere Contrains filtern?

Mit Django-Stamm versuche ich eine gewundene Datenbank-spezifische SQL-Anweisung mit Django-Aggregaten zu ersetzen. Als ein Beispiel sagen, dass ich eine Datenbank mit Tabellen für Blogs laufen auf vielen Gebieten aufgebaut haben (man denke .co.uk, .com, Etc.), die jeweils unter vielen Kommentare:

domains <- blog -> comment 

Die folgende SQL auf zählt Kommentare eine pro Domäne:

Domain.objects.annotate(Count('blogs__comments')) 

Einnahme dieses einen Schritt furth:

SELECT D.id, COUNT(O.id) as CommentCount FROM domain AS D 
LEFT OUTER JOIN blog AS B ON D.blog_id = B.id 
LEFT OUTER JOIN comment AS C ON B.id = C.blog_id 
GROUP BY D.id 

Dies wird mit leicht repliziert äh, ich möchte in der Lage sein, eine oder mehr Einschränkungen hinzuzufügen und zu replizieren die folgenden SQL:

SELECT D.id, COUNT(O.id) as CommentCount FROM domain AS D 
LEFT OUTER JOIN blog AS B ON D.blog_id = B.id 
LEFT OUTER JOIN comment AS C ON B.id = C.blog_id 
    AND C.active = True 
GROUP BY D.id 

Dies ist viel schwieriger zu replizieren, wie django auch auf der ganzen shaboodle mit einer WHERE-Klausel zu filtern scheint:

Domain.objects.filter(blogs__comments__active=True) 
       .annotate(Count('blogs__comments')) 

SQL kommt so etwas wie dieses aus:

SELECT ..., COUNT(comment.id) AS blog__comments__count FROM domain 
LEFT OUTER JOIN blog ON domain.blog_id = blog.id 
LEFT OUTER JOIN comment ON blog.id = comment.blog_id 
WHERE comment.active = True 
GROUP BY domain.id 
ORDER BY NULL 

Wie ich django überzeugen kann, die zusätzliche Einschränkung für die entsprechenden Pop LEFT OUTER JOIN? Dies ist wichtig, da ich eine Zählung für diese Blogs ohne Kommentare einschließen möchte.

+0

In re-researchign dieses Thema stieß ich auf diese Seite mit einer Umgehungslösung für den Augenblick: http://www.voteruniverse.com/Members/jlantz/blog/conditional-aggregates-in-django – Mat

Antwort

0

Ich weiß nicht, wie das mit der Django-Abfragesprache zu tun ist, aber Sie könnten immer eine rohe SQL-Abfrage ausführen. Falls Sie noch nicht wissen, wie das zu tun, hier ist ein Beispiel:

from django.db import connection 

def some_method(request, some_parameter): 
    cursor = connection.cursor() 
    cursor.execute('SELECT * FROM table WHERE somevar=%s', [some_parameter]) 
    rows = cursor.fetchall() 

Weiteres Detail ist in dem Django Buch Online verfügbar: http://www.djangobook.com/en/2.0/chapter05/

Suchen Sie den Abschnitt „Das‚Dumb‘Way to Datenbankabfragen in Views durchführen ". Wenn Sie nicht den "dummen" Weg benutzen wollen, bin ich nicht sicher, was Ihre Möglichkeiten sind.

+0

Ich war ursprünglich Ich habe es mit einer SQL-Abfrage gemacht, aber dann ging es in Form einer Birne, als ich von MySQL zu PostgreSQL wechselte. Ich habe es jetzt behoben, aber wäre immer noch nett, die Ral SQL-Abfrage zu vermeiden. – Mat

Verwandte Themen