質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

SQLAlchemy

SQLAlchemyとはPython 用のORMライブラリです。MIT Licenceのオープンソースとして提供されています。

Q&A

1回答

2917閲覧

Flask-SQLAlchemyを使ってクエリーのフィルタリングをしたい

ikeshi

総合スコア7

Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

SQLAlchemy

SQLAlchemyとはPython 用のORMライブラリです。MIT Licenceのオープンソースとして提供されています。

0グッド

0クリップ

投稿2020/02/26 01:15

編集2020/02/26 01:21

前提・実現したいこと

Flask-SQLAlchemyを用いてアプリケーションを作っています。
queryのfilterをかけて目的の行だけ取得したいのです。
実現したいことはdb.relationship()でつなげたテーブルの値を使って絞り込みをかけるやり方です。

backref側の値を使っての絞り込みは
filter(Master.id=="1")
という書き方で出来るのですが
結合したもう一方のテーブルの値を用いての絞り込み方がわかりません。

該当のソースコード

フィルタ処理を行いたいテーブルの構成は以下のようになっています。
Flask-SqlAlchemy-model

class Master(db.Model): __tablename__ = 'master' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.Text,nullable=True,default=None) serviceA = db.relationship('ServiceA',backref='master',lazy=False,uselist=False) serviceB = db.relationship('ServiceB',backref='master',lazy=False,uselist=False) class ServiceA(db.Model): __tablename__ = 'serviceA' id = db.Column(db.Integer, primary_key=True) master_id = db.Column(db.Integer,db.ForeignKey('master.id'),nullable=False) data = db.Column(db.Text,nullable=True,default=None) class ServiceB(db.Model): __tablename__ = 'serviceB' id = db.Column(db.Integer, primary_key=True) master_id = db.Column(db.Integer,db.ForeignKey('master.id'),nullable=False) data = db.Column(db.Text,nullable=True,default=None)

実現したいことをSQLで書くと以下のようになります。

SQL

1 SELECT 2 master.id AS id, 3 master.name AS name, 4 serviceA.data AS serviceA_data, 5 serviceB.data AS serviceB_data, 6 FROM 7 master_table AS master 8 LEFT OUTER JOIN 9 serviceA AS serviceA 10 ON master.id = serviceA.master_id 11 LEFT OUTER JOIN 12 serviceB AS serviceB 13 ON master.id = serviceB.master_id 14 WHERE 15 serviceA.serviceA_data = "hoge" 16 AND 17 serviceA.serviceB_data = "fuga" 18 ;

試したこと

master = Master.query.filter(Master.ServiceA.data=="hoge").filter(Master.ServiceB.data=="fuga").all()

  このような書き方でserviceAのテーブルの値を用いて絞り込みをしてみましたが、出来ませんでした。
まず
master = Master.query.filter(Master.ServiceA.data=="hoge").all()
の段階でうまく動作していません

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

データがないので動くかわからないですが、以下の様な感じでいかがでしょうか?

「# これはできない」の様な検索はできないようです。

python

1 2 ret = db.session.query(Master).outerjoin( 3 ServiceA, ServiceA.master_id == Master.id 4 ).outerjoin( 5 ServiceB, ServiceB.master_id == Master.id 6 ).filter( 7 db.and_( 8 ServiceA.data == 'hoge', 9 ServiceB.data == 'fuga' 10 11 ) 12 ).all() 13 14 print(ret) 15 16 # データはあるけど 17 ret2 = db.session.query(Master).all() 18 19 for n in ret2: 20 print(n.id) 21 print(n.name) 22 print(n.serviceA.data) 23 print(n.serviceA.data) 24 25 # これはできない 26 # ret2 = db.session.query(Master).filter( 27 # db.and_( 28 # Master.serviceA.data == 'hoge', 29 # Master.serviceB.data == 'fuga' 30 # ) 31 # ).all()

投稿2020/02/26 02:44

FiroProchainezo

総合スコア2424

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ikeshi

2020/02/27 05:08

ご回答ありがとうございます。 仰った方法で目的のデータを取得することが出来ました。 ありがとうございました。 しかし発行されているSQL文を見ると ''' FROM master LEFT OUTER JOIN serviceA ON serviceA.master_id = master.id LEFT OUTER JOIN serviceB ON serviceB.master_id = master.id LEFT OUTER JOIN serviceA AS serviceA_1 ON master.id = serviceA_1.master_id LEFT OUTER JOIN serviceB AS serviceB_1 ON master.id = serviceB_1.master_id WHERE serviceA.data = %(data_1)s .............. ''' このように書かれています。 tableのmodelの設定でrelationshipを元に自動でouter joinされたものとコードに記述したouter joinが両方働いていると思われます。 なんとかこのような処理を避ける方法はないでしょうか。
FiroProchainezo

2020/02/27 05:23

確認してないですが、シンプルに以下かもしれません ``` ret = db.session.query(Master, ServiceA, ServiceB).outerjoin( ).filter( db.and_( ServiceA.data == 'hoge', ServiceB.data == 'fuga' ) ).all() ```
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問