run query example engine create_engine close python sql join sqlalchemy

query - sqlalchemy python connection



Filtrado en una uniĆ³n izquierda en SQLalchemy (1)

Usando SQLalchemy quiero realizar una combinación externa izquierda y filtrar las filas que sí tienen una coincidencia en la tabla unida .

Estoy enviando notificaciones push, así que tengo una tabla de Notification . Esto significa que también tengo una tabla ExpiredDeviceId para almacenar device_ids que ya no son válidos. (No quiero simplemente eliminar las notificaciones afectadas, ya que el usuario podría volver a instalar la aplicación más adelante, momento en el cual las notificaciones deben reanudarse de acuerdo con los documentos de Apple).

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

Nota: puede haber múltiples notificaciones por device_id. No hay una tabla de "Dispositivos" para cada dispositivo.

Así que al hacer SELECT FROM Notification debería filtrar en consecuencia. Puedo hacerlo en SQL:

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

Pero, ¿cómo puedo hacerlo en SQLalchemy?

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

Alternativamente, podría hacer esto con una device_id NOT IN (SELECT device_id FROM ExpiredDeviceId) , pero parece menos eficiente.


¿Necesita estar retirando el ExpiredDeviceId en una tupla? Si no lo haces (es decir, solo te preocupas por live device_ids), entonces no puedes simplemente hacer:

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