with Session(engine) as session: customers = session.scalars(select(Customer)) for customer in customers: print(f"> Customer: #{customer.customer_id}") for order in customer.orders: print(f"> order #{order.order_id} at {order.order_datetime}")
对应的 SQL 语句:
1 2 3 4 5 6 7 8
-- This query gets all customers: SELECT customer.customer_id, ... FROM customer
-- The following SQL is executed once for each customer: SELECT "order".order_id AS order_order_id, ... FROM "order" WHERE "order".customer_id =%(param_1)s
优化方案 - 急切加载(Eager Loading)
1 2 3 4 5 6 7
with Session(engine) as session: customers = session.scalars( select(Customer).options(selectinload(Customer.orders))) for customer in customers: print(f"> Customer: #{customer.customer_id}") for order in customer.orders: print(f"> order #{order.order_id} at {order.order_datetime}")
对应的 SQL 语句:
1 2 3 4 5 6 7
SELECT customer.customer_id, ... FROM customer
-- This loads all the orders you need in one query: SELECT "order".order_id AS order_order_id, ... FROM "order" WHERE "order".customer_id IN (%(primary_keys_1)s, %(primary_keys_2)s, ...)
with Session(engine) as session: stmt = ( select( Customer.customer_id, Order.order_id, Order.order_datetime, ) .select_from(Customer) .join(Customer.orders) .order_by(Customer.customer_id) ) results = session.execute(stmt)
current_customer_id = None for row in results: customer_id = row.customer_id if current_customer_id != customer_id: current_customer_id = customer_id print(f"> Customer: #{current_customer_id}") print(f"> order #{row.order_id} at {row.order_datetime}")
对应的 SQL 语句:
1 2 3 4
SELECT customer.customer_id, "order".order_id, ... FROM customer JOIN "order" ON customer.customer_id = "order".customer_id ORDERBY customer.customer_id