Wie kann ich diese komplexe SQL-Abfrage mit Django ORM tun? (Sub-Abfrage mit einem Join)
Frage
Ich bin es gewohnt, meine eigenen SQL-Abfragen zu schreiben und ich versuche, auf die ganze ORM Sache zu gewöhnen, die heute so beliebt zu sein scheinen.
Hier ist die Abfrage:
SELECT * FROM routes WHERE route_id IN (
SELECT DISTINCT t.route_id FROM stop_times AS st
LEFT JOIN trips AS t ON st.trip_id=t.trip_id
WHERE stop_id = %s
)
wobei% s eine ganze Zahl.
Ich verwende Django-Standard ORM. Was ist der pythonic Weg, dies zu tun?
Einige Hintergrundinformationen: Die DB Ich verwende ist von einem GTFS (Google Transit-Feed-Spezifikation). Diese Abfrage soll eine Liste aller route
erhalten, die durch eine bestimmte stop
geht, aber die Informationen verknüpfen diese in der trips
Tabelle ist.
Diese Abfrage funktioniert gut für mich, so dass der einzige Grund, warum ich gefragt habe, ist, zu lernen.
Danke!
Lösung
Es wäre wahrscheinlich ein bisschen leichter herauszufinden, die geeignete Art und Weise, dies zu tun, wenn Sie haben, was Sie für den entsprechenden Models
verwendet hat.
Ich gehe davon aus so etwas wie die folgenden, basierend auf der Spezifikation Du von der Arbeit genannt:
class Route(models.Model):
#bunch of stuff
pass
class Stop(models.Model):
#bunch of stuff
stop_times = models.ManyToManyField(through=StopTime)
class StopTime(models.Model):
trip = models.ForeignKey(Trip)
stop = models.ForeignKey(Stop)
# bunch of additional meta about this M2M table
pass
class Trip(models.Model):
route = models.ForeignKey(Route)
# bunch of stuff
Wenn das der Fall ist ... Sie sollten so etwas wie
tun könnenRoute.objects.filter(trip__stop__id=my_stop_id)
alle Route
Objekte zu erhalten, die mit einem Primärschlüssel Stop
durch einen gegebenen id
geht gleich zu my_stop_id
, die ich angenommen bin eine ganze Zahl nach Ihrem Beitrag.
Ich entschuldige mich, wenn die Syntax ein wenig ausgeschaltet ist, da ich nicht zu tun, viele-zu-viele-Beziehungen mit einer expliziten zusätzliche Tabelle gebraucht. Einige Einstellung auch erforderlich sein können, wenn Sie zu haben (oder wählen), um den related_name
Parameter für alle die Fremdschlüssel verwenden oder many-to-many-Bereich.
Andere Tipps
Korrigieren Sie mich, wenn ich falsch liege, aber ich glaube nicht, dass Sie mit Django ORM in einer normalen Art und Weise tun können.
Es gibt keine Unterabfrage Unterstützung und mit einem normalen anschließen würde es auf Ihrer Datenbank abhängen, ob ein deutlich Ihnen helfen kann. Wenn Sie Postgres verwenden, als Sie es mit diesem Patch tun könnte: http://code.djangoproject.com/ticket / 6422
Die Abfrage so etwas wie dieses wäre:
Route.objects.filter(stop_time__trips__stop_id=...).distinct('stop_time__route_id')