2013-11-12 2 views
3

У меня есть небольшая проблема. У меня есть две таблицы SQL (ip и клиент), связанные третьей (ip_client). Я не использовал многие из многих отношений, поставляемых с SQLAlchemy, из-за сложной фильтрации, возникающей в некоторых моих запросах.SQLAlchemy force Left Join

Все в порядке, за исключением одного глупого варианта использования. Я хочу перечислить все IP без клиентов, и я не могу сделать это без внешнего соединения.

Outer Join занимает несколько секунд, когда один и тот же запрос с Left Join мгновен. Но невозможно избежать INNER JOIN, созданного SQL Alchemy. Я пробовал все отношения и перемещал внешние ключи, но он держит INNER JOIN.

Основываясь на той же проблеме, всякий раз, когда я пытаюсь перечислить все мои ips с столбцом, показывающим количество клиентов, запрос не будет возвращать ips с 0 клиентами (естественное поведение для INNER JOIN).

Есть ли способ заставить это?

Кстати это мой запрос:

query = (session.query(Ip, func.count(Client.id)) 
    .join(ClientIp, ClientIp.ip_id==Ip.id) 
    .join(Client, Client.id==ClientIp.client_id) 
    .group_by(Ip.id)) 

Есть хитрость в создании запроса или функции, чтобы заставить LEFT JOIN присоединиться?

ответ

11

outerjoin Просто используйте вместо join где это уместно:

query = (session.query(Ip, func.count(Client.id)). 
    outerjoin(ClientIp, ClientIp.ip_id==Ip.id). 
    outerjoin(Client, Client.id==ClientIp.client_id). 
    group_by(Ip.id) 
) 

Производительность на OUTER JOIN является еще одним вопросом, где наличие indices на ForeignKey колонны может быть огромной помощью.

+0

Я создал индекс, и это очень быстро, хотя это не меняет мою проблему со счетом (вторая проблема). Внешнее соединение будет возвращаться только 0, Inner JOIN вернется только> 0. Как получить все в одном запросе? – SIkwan

+1

Я не думаю, что ваше утверждение относительно 'OUTER JOIN', возвращающего только 0, является правильным. Фактически, «OUTER JOIN» должен вернуть все. Ты это пробовал? – van

+0

Вы правы, я сделал только внешнее соединение на одном из моих двух объединений. Хорошо работать с двумя из них. Большое спасибо ! – SIkwan