Sqlalchemy: 联合加载 + 限制
给定以下语句:
p = db.query(Profile).options(joinedload('*')).filter_by(id=p.id).limit(1).one()
我会得到一个子查询加上一个连接,而不是一个“纯粹”的连接:
SELECT [...]
FROM (SELECT profile.id AS profile_id, ...
FROM profile
WHERE profile.id = %(id_1)s
LIMIT %(param_1)s) AS anon_1 LEFT OUTER JOIN city AS city_1 ON city_1.id = anon_1.profile_city LEFT OUTER JOIN country AS country_1 ON country_1.id = city_1.country LEFT OUTER JOIN state AS state_1 ON country_1.id = state_1.country LEFT OUTER JOIN state AS state_2 ON state_2.id = city_1.state LEFT OUTER JOIN country AS country_2 ON country_2.id = state_2.country LEFT OUTER JOIN state AS state_3 ON state_3.id = city_1.state LEFT OUTER JOIN country AS country_3 ON country_3.id = state_3.country LEFT OUTER JOIN starred AS starred_1 ON anon_1.profile_id = starred_1.star LEFT OUTER JOIN profiletext AS profiletext_1 ON anon_1.profile_id = profiletext_1.profile LEFT OUTER JOIN starred AS starred_2 ON anon_1.profile_id = starred_2.idprofile LEFT OUTER JOIN photo AS photo_1 ON anon_1.profile_id = photo_1.profile LEFT OUTER JOIN gps AS gps_1 ON anon_1.profile_id = gps_1.idprofile
但我真正需要的是:
SELECT ...
FROM profile LEFT OUTER JOIN city AS city_1 ON city_1.id = profile.city LEFT OUTER JOIN country AS country_1 ON country_1.id = city_1.country LEFT OUTER JOIN state AS state_1 ON country_1.id = state_1.country LEFT OUTER JOIN state AS state_2 ON state_2.id = city_1.state
LEFT OUTER JOIN country AS country_2 ON country_2.id = state_2.country LEFT OUTER JOIN state AS state_3 ON state_3.id = city_1.state LEFT OUTER JOIN country AS country_3 ON country_3.id = state_3.country LEFT OUTER JOIN starred AS starred_1 ON profile.id = starred_1.star LEFT OUTER JOIN profiletext AS profiletext_1 ON profile.id = profiletext_1.profile LEFT OUTER JOIN starred AS starred_2 ON profile.id = starred_2.idprofile LEFT OUTER JOIN photo AS photo_1 ON profile.id = photo_1.profile LEFT OUTER JOIN gps AS gps_1
ON profile.id = gps_1.idprofile
WHERE profile.id = 4
limit 1;
也就是说,不能有子查询。
数据库:postgresql 9.2
1 个回答
3
这看起来是正常的行为,按照急切加载的原则来讲。
在使用连接急切加载时,如果查询中包含一些会影响返回行的修改器,比如使用 DISTINCT(去重)、LIMIT(限制返回数量)、OFFSET(偏移量)或类似的东西,最终生成的语句会先被包裹在一个子查询中,然后专门用于连接急切加载的连接会应用到这个子查询上。SQLAlchemy 的连接急切加载做得非常细致,确保它不会影响查询的最终结果,只是改变了集合和相关对象的加载方式,无论查询的格式是什么样的。
我知道这是个老问题,但生成的 SQL 为什么不工作呢?