2016-05-06 14 views
0

私は2つのテーブルtable_atable_bを持っています。 table_b.code_btable_asqlalchemy joinedload queryはカウントできません

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

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

の外部キーである私は、2つのテーブルを結合し、この結果を取得したい:

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にすると、正しい結果になります。しかし、私はrows2を実行するとエラーが発生します。 DatabaseError:(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 

それは明らかです2つのテーブルがではなく、が結合されています。

しかし、ちょうど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:

Q:私はwhere_strを使うのはなぜ?

A:HTMLページでは、クエリビルダ(http://querybuilder.js.org/)を使用してクエリフィルタを取得しています(おそらく複雑です)。だから、SQLAlchemyクエリ・ファイラーに渡すと便利です。

これを実装する方法はありますか?


EDIT2: ソリューション:

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

答えて

1

これは間違っています:SQLAlchemyのは、あなたのwhere_strcode_bがテーブルを参照することになっていることを知っていることになっている方法

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

B?

試してください:あなたもjoinedloadを実行する必要がある場合は

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

、次の操作を行います。

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

おかげで、あなたは合格する必要があるという理由だけで、私の質問を更新:) – seizetheday

+0

@seizethedayを参照してください。フロントエンドからフィルタインしても、 'text'コンストラクトを使う必要はありません。それにもかかわらず、あなたは 'text'構造体を使っていますが、それ自体は問題ではありません。問題は '.join'の代わりに' joinedload'を使用することです。 – univerio

+0

ありがとう、人生節約! – seizetheday

関連する問題