应用order_by时对表的引用无效

时间:2016-01-06 08:01:44

标签: python sql sqlalchemy

我有SqlAlchemy数据模型(错过了其他字段):

session.query(District)\
    .options(joinedload(District.region))\
    .order_by(Region.name, Region.id)\
    .slice(0, 25)

并构建此查询:

ProgrammingError: (ProgrammingError) invalid reference to FROM-clause entry for table "region"

查询发出错误ORDER BY。调查后发现原始SQL错误的原因。 SELECT district.id AS district_id, district.name AS district_name, district.region_id AS district_region_id, region_1.id AS region_1_id FROM district LEFT OUTER JOIN region AS region_1 ON region_1.id = district.region_id ORDER BY region.name, region.id LIMIT 25 子句不正确:

ORDER BY

进入region子句使用region_1而不是正确的别名<tags-input ng-model="recps" display-property="recipient" replace-spaces-with-dashes="false" on-tag-removing="removeRecipient($tag)" allowed-tags-pattern="^[A-Za-z0-9]+([-_.][A-Za-z0-9]+)*@[A-Za-z0-9]+([-_.][A-Za-z0-9]+)*.[A-Za-z]{2,5}$" on-invalid-tag="invalidTagInput($tag)" ng-focus="validData.validRecipients=true;"> </tags-input> <div class="email-address box" ng-show="!validData.validRecipients"> {{validationMsg}} </div> //js code here $scope.invalidTagInput = function(tag) { $scope.validData.validRecipients = false; }; ,这会引发错误。

在这种情况下如何构建正确的查询?

1 个答案:

答案 0 :(得分:1)

查看sqlalchemy文档The Zen of Eager Loading

他们准确描述了您的问题,解决方案将是:

In [10]:
    ​
q = session.query(District)\
    .join(District.region)\
    .options(joinedload(District.region))\
    .order_by(Region.name, Region.id)\
    .slice(0, 25)
​
print(q)
​
SELECT district.id AS district_id, district.region_id AS district_region_id, district.name AS district_name, region_1.id AS region_1_id, region_1.name AS region_1_name 
FROM district JOIN region ON region.id = district.region_id LEFT OUTER JOIN region AS region_1 ON region_1.id = district.region_id ORDER BY region.name, region.id
 LIMIT ? OFFSET ?

(我必须将名字添加到您发布的课程中。)

相关引用:

  

我们在上面看到的是我们使用Query.join()来提供JOIN   我们想在后续查询标准中使用的条款,而我们的条款   joinload()的用法只关心它的加载   User.addresses集合,用于结果中的每个用户。在这种情况下,   这两个连接最可能看起来多余 - 它们是。

(在您的情况下,将User.addresses替换为District.region

如果您按照链接进行操作,可以在一个联接中再次进行此操作:

In [15]:

from sqlalchemy.orm import aliased, outerjoin, contains_eager
​
ralias = aliased(Region)
​
q2 = session.query(District).\
    outerjoin(ralias, District.region).\
    options(contains_eager(District.region, alias=ralias)). \
    order_by(Region.name, Region.id).\
    slice(0, 25)
​
print(q2)
​
SELECT region_1.id AS region_1_id, region_1.name AS region_1_name, district.id AS district_id, district.region_id AS district_region_id, district.name AS district_name 
FROM district LEFT OUTER JOIN region AS region_1 ON region_1.id = district.region_id ORDER BY region.name, region.id
 LIMIT ? OFFSET ?

希望它有所帮助。