Comment puis-je faire cette requête SQL complexe en utilisant Django ORM? (Sous-requête avec une jointure)
Question
Je suis habitué à écrire mes propres requêtes SQL et je suis en train de nous habituer à toute chose ORM qui semble être si populaire de nos jours.
Voici la requête:
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
)
où% s est un nombre entier.
J'utilise ORM par défaut de Django. Quelle est la façon la plus pythonique de le faire?
Quelques informations de fond: Le DB J'utilise est d'un GTFS (Google spécification d'alimentation Transit). Cette requête est censée obtenir une liste de tous les route
qui passe par un stop
particulier, mais l'information est un lien entre ces dans la table trips
.
Cette requête fonctionne très bien pour moi, la seule raison pour laquelle je demande est d'apprendre.
Merci!
La solution
Il serait probablement un peu plus facile à comprendre la façon appropriée de le faire si vous aviez ce que vous utilisiez pour le Models
concerné.
Je suppose quelque chose comme ce qui suit, sur la base du cahier des charges vous avez mentionné le travail à:
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
Si tel est le cas ... vous devriez être en mesure de faire quelque chose comme
Route.objects.filter(trip__stop__id=my_stop_id)
pour obtenir tous les objets Route
qui passent par un Stop
donné avec un id
de clé primaire égale à my_stop_id
, qui je suppose est un entier selon votre message.
Je me excuse si la syntaxe est un peu loin, comme je l'ai pas eu besoin de faire beaucoup à plusieurs relations en utilisant une table supplémentaire explicite. Un ajustement peut également être nécessaire si vous avez (ou choisissez) utiliser le paramètre related_name
pour toutes les clés étrangères ou les nombreux à plusieurs champ.
Autres conseils
moi si je me trompe, mais je ne pense pas que vous pouvez le faire avec Django ORM de manière normale.
Il n'y a pas de support et avec une sous-requête normale se joindre à elle dépendra de votre base de données si distincte pourrait vous aider. Si vous utilisez Postgres que vous pouvez le faire avec ce patch: http://code.djangoproject.com/ticket / 6422
La requête serait quelque chose comme ceci:
Route.objects.filter(stop_time__trips__stop_id=...).distinct('stop_time__route_id')