Created
July 20, 2021 13:31
-
-
Save leontrolski/0dbc3ad3b2b49b830dbd7ade374524e2 to your computer and use it in GitHub Desktop.
SQLAlchemy join types
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- given tables a, b | |
-- equivalent SQLAlchemy models A, B | |
-- a has many b, joined on a_id | |
-- a has l non-id fields, b has m | |
a_id | x1 | x2 | x... | xl | |
b_id | a_id | y1 | y2 | y... | ym | |
-- let's do a joined load: | |
session.query(A).options(joinedload(B)) | |
-- does: | |
SELECT a.a_id, a.x1, a.x2 ..., b.b_id, b.a_id, b.y1, ... | |
FROM a | |
JOIN b on a.a_id = b.b_id | |
-- number of queries: 1 | |
-- query returns data: | |
a_id | x1 | x2 | x... | xl | b_id | a_id | y1 | y2 | y... | ym | |
_some data_ | |
-- if `l` is large, let's say 1kb per row | |
-- and we find 10 `a`s matching our query | |
-- and there are 100 `b`s per `a` | |
-- we end up unnecessarily sending | |
-- 1kb * (100 - 1) * 10 = 990kb of data over the wire | |
-- (that we discard when SQLAlchemy nests our data Python-side) | |
-- to prevent this, we do: | |
session.query(A).options(selectin(B)) | |
-- does | |
SELECT a.a_id, a.x1, a.x2 ..., | |
FROM a | |
SELECT b.b_id, b.a_id, b.y1, ... | |
WHERE b.a_id in (the a_ids from the previous query) | |
-- number of queries: 1 + 1 = 2 | |
-- or just number of queries = number of joins | |
-- queries return | |
a_id | x1 | x2 | x... | xl | |
_some data_ | |
b_id | a_id | y1 | y2 | y... | ym | |
_some data_ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment