2016-01-06 59 views
0

我有SQLAlchemy的數據模型(其他字段被遺漏):無效參照表而ORDER_BY施加

class Region(Base): 
    __tablename__ = 'region' 
    id = db.Column(db.Integer, primary_key=True) 

class District(Base): 
    __tablename__ = 'district' 
    id = db.Column(db.Integer, primary_key=True) 
    region_id = db.Column(db.Integer, ForeignKey(Region.id)) 
    region = relationship(Region) 

和構建這個查詢:

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"。調查後發現該錯誤的原始SQL原因。 ORDER BY條款是不正確的:

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的,這引發了一個錯誤。

如何在這種情況下構建正確的查詢?

回答

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 條款,我們希望在隨後的查詢條件使用,而我們的 使用joinedload的()僅針對結果中的每個用戶加載 User.addresses集合。在這種情況下, 這兩個連接最有可能看起來是多餘的 - 它們是。

(用District.region代替User.addresses)。

如果你跟隨鏈接,你可以在一個再讓它加入這樣的:

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 ? 

希望它能幫助。