在SQLalchemy中对左连接进行过滤
我想用SQLalchemy来做一个左外连接,并且过滤掉在连接表中有匹配的行。
我正在发送推送通知,所以我有一个Notification
表。这也意味着我有一个ExpiredDeviceId
表,用来存储那些不再有效的设备ID。(我不想直接删除受影响的通知,因为用户可能会重新安装应用,这样通知就应该根据苹果的文档恢复。)
CREATE TABLE Notification (device_id TEXT, time DATETIME);
CREATE TABLE ExpiredDeviceId (device_id TEXT PRIMARY KEY, expiration_time DATETIME);
注意:每个设备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 个回答
16
你需要把过期的设备ID放在一个元组里吗?如果不需要(也就是说,你只关心活跃的设备ID),那你是不是可以直接这样做:
sess.query(
Notification
).outerjoin(
(ExpiredDeviceId, Notification.device_id == ExpiredDeviceId.device_id)
).filter(
ExpiredDeviceId.expiration_time == None
)