Фильтрация по левому соединению в SQLalchemy - PullRequest
18 голосов
/ 07 января 2011

Используя SQLalchemy, я хочу выполнить левое внешнее объединение и отфильтровать строки, в которых есть совпадения в объединенной таблице .

Я отправляю push-уведомления, поэтому у меня есть таблица Notification. Это означает, что у меня также есть таблица ExpiredDeviceId для хранения device_ids, которые больше не действительны. (Я не хочу просто удалять затронутые уведомления, поскольку пользователь может позже переустановить приложение, после чего уведомления должны возобновиться в соответствии с документами Apple.)

CREATE TABLE Notification (device_id TEXT, time DATETIME);
CREATE TABLE ExpiredDeviceId (device_id TEXT PRIMARY KEY, expiration_time DATETIME);

Примечание: может быть несколько уведомлений на device_id. Для каждого устройства нет таблицы «Устройство».

Так что при выполнении SELECT FROM Notification я должен фильтровать соответственно. Я могу сделать это в SQL:

SELECT * FROM Notification 
    LEFT OUTER JOIN ExpiredDeviceId 
    ON Notification.device_id = ExpiredDeviceId.device_id
WHERE expiration_time IS NULL

Но как я могу это сделать в SQLalchemy?

sess.query(
    Notification, 
    ExpiredDeviceId
).outerjoin(
    (ExpiredDeviceId, Notification.device_id == ExpiredDeviceId.device_id)
).filter(
    ???
)

С другой стороны, я мог бы сделать это с предложением device_id NOT IN (SELECT device_id FROM ExpiredDeviceId), но это кажется гораздо менее эффективным.

1 Ответ

14 голосов
/ 10 января 2011

Нужно ли возвращать ExpiredDeviceId в кортеже? Если вы этого не сделаете (т.е. вы просто заботитесь о живых идентификаторах устройств), то вы не можете просто сделать:

sess.query(
    Notification
).outerjoin(
    (ExpiredDeviceId, Notification.device_id == ExpiredDeviceId.device_id)
).filter(
    ExpiredDeviceId.expiration_time == None
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...