SQLAlchemy filter検索方法まとめ

Web開発

皆さん、こんにちは。

今回もまたSQLAlchemyネタです。

SQLAlchemyで、モデルを介してDBからデータを取得したいときに、どうのように記載するのか。

について書きます。

※CRUD用にファイルを1つ用意している想定で書きます。

filterで検索結果を絞る場合

例えば、crud_user.pyというファイルがあったとします。

単にfilterで検索する場合は、以下のように書けます。

from typing import Optional

from sqlalchemy.orm import Session

from crud.base import CRUDBase
from models.user import User
from schemas.user import UserCreate, UserUpdate


class CRUDUser(CRUDBase[User, UserCreate, UserUpdate]):
    def get_by_name(
        self, db: Session, *, name: str
    ) -> Optional[User]:
        return db.query(User).filter(User.name == name).first()


user = CRUDUser(User)

すこし、説明を追加します。

db.query(User).filter(User.name == name).first()

この部分で検索しているわけですが、queryの引数に検索対象のモデルをいれて、

そのあとにfilterを追加するだけです。

filter内には、検索するモデルのカラムの条件を記述すればOKです。

腕の例では、単にnameと等しいものを取得するように書いてます。

最後のfirst()も大切な部分です。

これが付く場合は、Userモデルが返ります。

しかし、付かない場合は、sqlalchemy.orm.query.Queryが返ります。

複数返す場合は、first()ではなく、all()を最後につければOKです。

リスト内のデータに含まれているのかで検索したい場合

例えば、リスト内のデータに含まれているものを取得したいというときもあるかと思います。

そんなときは、以下のように書けます。

def get_by_ids(
    self, db: Session, *, id_list: List[str]
) -> List[User]:
    return db.query(User).filter(User.id.in_(id_list)).all()

filter内に、検索対象のカラム.in_(リスト)でいけます。

上の例は、複数のidのいずれかに当てはまるものを取得するものです。

User.id.in_(id_list)でidのリストを検索条件に与えてます。

order_byで順序を並び替える場合

最後に、order_byで検索結果を並び替える場合です。

from sqlalchemy import asc, desc

...

def get_order_by_created(
    self, db: Session, *, name: str
) -> List[User]:
    return db.query(User).filter(User.name == name).order_by(desc(User.created_at)).all()

asc(昇順), desc(降順)をorder_by内で上記のように、並び替え対象のカラムと共に指定すればOKです。

上記のように記載すると、created_atが最新のもの順で、かつnameが等しいものが取得できます。

※今回、サンプルなんで一行で書いてしまいましたが、flake8などのチェックで一行当たりの長さで引っかかると思いますので、適度に改行したほうがいいですね。

以上です。でわでわ!

タイトルとURLをコピーしました