今回はsqlalchemyによるサブクエリの使い方についてです。
こちらのサンプルの対象のデータベースはPostgresqlです。
サンプルコード
サンプルテーブルは以下のようなものを用意
sample_code:キーとなるコード
ymd:日付
high_score:ハイスコア
low_score:ロースコア
クエリ仕様
サンプルテーブルは日ごとにスコアが登録されているものとして、
SampleModelのレコードで、ハイスコアとロースコアが0になっているものに
sampleコード単位にハイスコア、ロースコアの平均を出して更新するというイメージです。
# サブクエリ
sub_query = (
session.query(
SampleModel.sample_code,
func.avg(SampleModel.high_score).label(
"average_high"
),
func.avg(SampleModel.low_score).label(
"average_low"
),
)
.filter(
SampleModel.high_score != 0.0,
SampleModel.low_score != 0.0,
)
.group_by(SampleModel.sample_code)
).subquery("sub")
# メインクエリ
update_stmt = (
update(SampleModel)
.values(
high_score=sub_query.c.average_high,
low_score=sub_query.c.average_low,
)
.where(
and_(
SampleModel.sample_code
== sub_query.c.sample_code,
SampleModel.high_score == 0.0,
SampleModel.low_score == 0.0,
)
)
)
発行されるクエリ
上記のクエリビルダーにて発行されるSQLは以下のようになります。
update SampleModel
set high_score = sub.average_high,
low_score = sub.average_low
from (
select avg(SampleModel.high_score) as average_high,
avg(SampleModel.low_score) as average_low
from SampleModel
where high_score != 0
and low_scrore != 0
group by sample_code
) sub
where sample_code = sub.sample_code
and high_score = 0
and low_scrore = 0
解説
sqlalchemyで複雑なクエリを組む場合は、サブクエリの導入を検討し、
各サブクエリは変数として部分的に作成することが良いと思います。
サブクエリにはqueryの最後にsubquery(“エイリアス名”)をつけて上げることで、
クエリビルダーの中でそのサブクエリの変数が使用できるようになります。
また、サブクエリの変数を介して、selectした項目を使用する場合には、
変数.c.項目名(.labelによりエイリアスを設定知る場合にはその名前)と
することで使用できます。

20代前半までは東京で音楽をやりながら両手の指以上の業種でアルバイト生活をしていましたが、某大手プロバイダのテレアポのバイトでPCの知識の無さに愕然とし、コンピュータをもっと知りたい!と思ったことをきっかけに25歳の時にITの世界に未経験で飛び込みました。
紆余曲折を経て、現在は個人事業主としてお仕事させていただいており、10年ほどになります。
web制作から企業システム構築、ツール開発など、フロントエンドもバックエンドもサーバーもDBAも依頼があれば何でもやってきた雑食系エンジニアです。
今風にいうとフルスタックエンジニアということになるのでしょうか??
→ 詳細プロフィールというか、生い立ちはこちら
→スキルシートをご覧になる場合はこちら
→お仕事のご依頼やお見積りなどお問い合わせはこちらから!



コメント