【问题标题】:Sqlalchemy: joinedload + limitSqlalchemy:joinedload + limit
【发布时间】:2013-03-21 16:40:15
【问题描述】:

鉴于以下陈述:

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

【问题讨论】:

  • 你用这个针对什么数据库?

标签: python sql sqlalchemy subquery limit


【解决方案1】:

根据The Zen of Eager Loading,这似乎是预期的行为

当使用联合预加载时,如果查询包含一个修饰符 影响从外部返回到连接的行,例如在使用时 DISTINCT、LIMIT、OFFSET 或等效项,完成的语句是 首先包裹在子查询中,而连接专门用于 加入的急切加载应用于子查询。 SQLAlchemy 已加入 急切的装载会加倍努力,然后再走十英里,以 绝对保证不影响查询的最终结果, 仅加载集合和相关对象的方式,无论 查询的格式是什么。

我意识到这是一个老问题,但是生成的 SQL 不起作用是有原因的吗?

【讨论】:

  • 这是否意味着如果在查询中某处存在带有joinedload的limit/distinct/offset的查询,那么joinedload被视为子查询负载?
  • 好像是这样的,是的。我不确定 sqlalchemy 的内部是否将其转换为 subqueryload,但它似乎具有相同的结果。
猜你喜欢
  • 2018-06-02
  • 1970-01-01
  • 1970-01-01
  • 2023-03-25
  • 2011-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-05
相关资源
最近更新 更多