Как я могу сделать этот сложный SQL-запрос, используя Django ORM?(подзапрос с объединением) - PullRequest
3 голосов
/ 28 октября 2010

Я привык писать свои собственные SQL-запросы и пытаюсь привыкнуть ко всему, что ORM сейчас так популярно.

Вот запрос:

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
)

где% s - целое число.

Я использую ORM по умолчанию в Django.Какой самый питонический способ сделать это?

Некоторая справочная информация: Я использую БД из GTFS (спецификация фида Google Transit).Предполагается, что этот запрос получит список всех route, проходящих через определенный stop, однако информация, связывающая их, находится в таблице trips.

Этот запрос прекрасно работает для меня, поэтомуЕдинственная причина, по которой я спрашиваю, - это учиться.

Спасибо!

Ответы [ 2 ]

1 голос
/ 29 октября 2010

Вероятно, было бы немного проще найти подходящий способ сделать это, если бы у вас было то, что вы использовали для соответствующего Models.

Я предполагаю что-то вроде следующего, основанногов спецификации, которую вы упомянули, работая с:

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

Если это так ... вы должны иметь возможность сделать что-то вроде

Route.objects.filter(trip__stop__id=my_stop_id)

, чтобы получить все Route объекты, которые идутчерез данный Stop с первичным ключом id, равным my_stop_id, который, как я предполагаю, является целым числом согласно вашему сообщению.

Я извиняюсь, если синтаксис немного отключен, так как яне нужно было делать отношения «многие ко многим», используя явную дополнительную таблицу.Некоторая корректировка может также потребоваться, если вам нужно (или вы захотите) использовать параметр related_name для любых внешних ключей или поля «многие ко многим».

1 голос
/ 28 октября 2010

Поправьте меня, если я ошибаюсь, но я не думаю, что вы можете сделать это с Django ORM обычным способом.

Поддержка подзапросов отсутствует, и при обычном объединении будет зависеть ваша база данных, если вам может помочь отдельный. Если вы используете Postgres, вы можете сделать это с помощью этого патча: http://code.djangoproject.com/ticket/6422

Запрос будет выглядеть примерно так:

Route.objects.filter(stop_time__trips__stop_id=...).distinct('stop_time__route_id')
...