Фильтрация в левом соединении в SQLalchemy
Использование SQLalchemy Я хочу выполнить левое внешнее соединение и отфильтровать строки, которые имеют совпадение в объединенной таблице.
Я отправляю push-уведомления, поэтому у меня есть таблица Notification
. Это означает, что у меня также есть таблица ExpiredDeviceId
для хранения идентификаторов устройств, которые больше не действительны. (Я не хочу просто удалять затронутые уведомления, поскольку пользователь может позже переустановить приложение, после чего уведомления должны возобновиться в соответствии с документами 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
Вам нужно оттянуть ExpiredDeviceId в кортеже? Если вы этого не сделаете (то есть просто заботитесь о живых идентификаторах устройств), то вы не можете просто сделать:
sess.query(
Notification
).outerjoin(
(ExpiredDeviceId, Notification.device_id == ExpiredDeviceId.device_id)
).filter(
ExpiredDeviceId.expiration_time == None
)