SQLalchemyの使用左外部結合を実行し、は、結合テーブルで一致する行をフィルタリングします。SQLalchemyの左結合でのフィルタリング
私はプッシュ通知を送信していますので、私はNotification
テーブルを持っています。これは、もはや有効ではないdevice_idsを格納するテーブルが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)
句でこれを行うことができますが、それは仕方少ない効率的なようです。
あなたはそうです。私は間違って、ExpiredDeviceIdが実際にオブジェクト参照であると仮定しました。一致する行がない場合、ExpiredDeviceId自体はNoneになります。しかし、実際にはクラス(テーブル)名であり、式は有効なSQLにコンパイルされます。 (私の質問の言葉遣いのために、私はそれが* IS * Noneであるかどうかを調べる必要があることに注意してください) –
ああ、良い点、コードを編集して混乱を避けるために –
'ExpiredDeviceId.expiration_time is None'これは.filter()に渡される前に常にFalseに評価され、予期しない動作を引き起こします(SQLを読み込むときにクエリを読み込むと予期しない動作が発生します)。 '=='を使用してください。 – Baczek