私は2つのテーブルtable_a
とtable_b
を持っています。 table_b.code_b
がtable_a
sqlalchemy 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))
おかげで、あなたは合格する必要があるという理由だけで、私の質問を更新:) – seizetheday
@seizethedayを参照してください。フロントエンドからフィルタインしても、 'text'コンストラクトを使う必要はありません。それにもかかわらず、あなたは 'text'構造体を使っていますが、それ自体は問題ではありません。問題は '.join'の代わりに' joinedload'を使用することです。 – univerio
ありがとう、人生節約! – seizetheday