2016-05-06 40 views
0

我有兩個表table_atable_btable_b.code_b是的table_asqlalchemy joinedloaded query can not make counting

table_a 
code_a, val 
----------- 
aaa,100 

table_b 
code_b, name 
------------ 
aaa, name1 

我想這個結果與連接兩個表的外鍵:

table_result 
code_a,val,name 
--------------- 
aaa,100,name1 

以下是Python代碼:

class A(db.Model): 
    __tablename__ = 'table_a' 
    code_a = Column(String(20), ForeignKey("table_b.code_b"), primary_key=True) 
    val = Column(Float) 
    b = relationship("B", backref=backref('table_b')) 


class B(db.Model): 
    __tablename__ = 'table_b' 
    code_b = Column(String(20), primary_key=True) 
    name = Column(String(100)) 
    a = relationship("A", backref="table_a") 

where_str = "code_b='aaa'" 
q = A.query.options(joinedload_all(A.b)).filter(text(where_str)) 

rows1 = [i.serialize for i in q.all()] # CORRECT 
rows2 = [i.serialize for i in q.paginate(1,10,False)] # ERROR 

如果我只是全部查詢得到rows1,這是正確的結果。不過,我會得到錯誤與運行rows2DatabaseError:(cx_Oracle.DatabaseError)ORA-00904: 「CODE_B」

我調試這個錯誤與打印的SQL語句:

SELECT count(*) AS count_1 
FROM (SELECT "table_a".code_a AS "table_a_code_a", 
FROM "table_a" 
WHERE code_b = 'aaa') anon_1 

很明顯那兩張桌子是不是加入。

但是,如果只是q.all(),將SQL語句:

SELECT "table_a".code_a AS "table_a_code_a", 
FROM "table_a" LEFT JOIN "table_b" 
WHERE code_b = 'aaa' 

這是正確的。

那麼,如何在製作分頁時得到正確的結果。


EDIT1:

問:爲什麼我使用where_str

答:在HTML頁面中,我使用查詢生成器(http://querybuilder.js.org/)來獲取查詢過濾器(可能很複雜)。所以,傳遞給SQLAlchemy查詢文件管理器很方便。

有沒有更好的方法來實現呢?


EDIT2: 解決方案:

q = A.query.join(A.b).options(contains_eager(A.b)).filter(text(where_str)) 

回答

1

這是不正確的:

where_str = "code_b='aaa'" 
q = A.query.options(joinedload_all(A.b)).filter(text(where_str)) 

SQLAlchemy的應該是怎樣知道你的where_strcode_b應該參考表B'

嘗試:

q = A.query.join(A.b).filter(B.code_b == "aaa") 

如果您還需要執行joinedload,做到這一點:

q = A.query.join(A.b).options(contains_eager(A.b)).filter(B.code_b == "aaa") 
+0

感謝,請參閱我的問題更新:) – seizetheday

+0

@seizetheday僅僅因爲你需要通過從前端過濾並不意味着您需要使用「文本」結構。無論如何,你使用「文本」結構本身並不是問題;問題是你使用'joinedload'而不是'.join'。 – univerio

+0

謝謝,救命! – seizetheday