SQLAlchemy使用笔记--SQLAlchemy ORM(三)

时间:2022-12-01 03:52:55

参考:
http://docs.sqlalchemy.org/en/rel_1_0/orm/tutorial.html#eager-loading

预先加载

前面的代码,因为是lazy load,当我们调用User.addresses 时,sqlalchemy才会发出sql语句去取addresses,
比如:

query = session.query(User).all()
for user in query:
print(user.addresses)

如果有10个用户,for循环10次,就会发10个取user中address信息的sql请求,这样很没有效率。
可以使用预先加载,在一个sql请求中吧User.addresses 都取出来。

subquery 加载

看例子:

users = session.query(User).options(subqueryload(User.addresses)).all()

发出的sql

SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password
FROM users;


SELECT addresses.id AS addresses_id, addresses.email_address AS addresses_email_address, addresses.user_id AS addresses_user_id, anon_1.users_id AS anon_1_users_id
FROM (SELECT users.id AS users_id
FROM users) AS anon_1 JOIN addresses ON anon_1.users_id = addresses.user_id ORDER BY anon_1.users_id, addresses.id;

当取出users时,会发出2个sql,第一个sql是取出所有user的基本信息,第二个sql时取出所有user的address信息。

joinedload 加载

joinedload 加载会使用 LEFT OUTER JOIN 来加载信息

users = session.query(User).options(joinedload(User.addresses)).all()
SELECT users.id AS users_id, users.name AS users_name, users.fullname AS users_fullname, users.password AS users_password, addresses_1.id AS addresses_1_id, addresses_1.email_address AS addresses_1_email_address, addresses_1.user_id AS addresses_1_user_id
FROM users LEFT OUTER JOIN addresses AS addresses_1 ON users.id = addr;


明确的使用join

当已经明确大join了User.addresses 后,可以使用contains_eager来加载address的信息。

users = session.query(User).join(User.addresses).options(contains_eager(User.addresses)).all()