6

次のステートメントがあるとします。

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

4

1 に答える 1

3

これはThe Zen of Eager Loadingによると予想される動作のようです

結合された熱心な読み込みを使用する場合、DISTINCT、LIMIT、OFFSET、または同等のものを使用する場合など、結合の外部に返される行に影響を与える修飾子がクエリに含まれている場合、完了したステートメントは最初にサブクエリ内にラップされ、結合は特に結合された熱心な読み込みがサブクエリに適用されます。SQLAlchemy の結合された熱心な読み込みは、クエリの形式に関係なく、クエリの最終結果に影響を与えず、コレクションと関連オブジェクトが読み込まれる方法のみに影響を与えることを完全に保証するために、さらに 1 マイル、さらに 10 マイル進みます。

これは古い質問だと思いますが、生成された SQL が機能しない理由はありますか?

于 2013-05-06T16:49:56.613 に答える