[小ネタ] flake8利用時にSQLAlchemyでBoolean型のフィルタを掛けるときの注意点

2021.02.22

こんにちは!DA(データアナリティクス)事業本部 インテグレーション部の大高です。

先日、SQLAlchemyを利用しているPythonの環境にflake8を導入したのですが、思いがけない問題を起こしたので、自分自身への備忘録としても残しておきたいと思います。

前提

今回の環境は以下のような環境です。

  • SQLAlchemyを利用したPythonプロジェクト環境
  • flake8を導入して、Visual Studio Codeでコードを自動チェックするようにしている

起きた問題

SQLAlchemyでフィルタを使う際に、以下のようなコードがあるとします。

users = session.query(User).filter(User.deleted == False)

このようなコードはFalseとの比較演算子として==を利用しているのでflake8からお叱りをうけます。

comparison to False should be 'if cond is False:' or 'if not cond:'flake8(E712)

これは、もっともなエラーなのですが、実はSQLAlchemyのフィルタにおいては==が正しくisにしてしまうと、期待通りの結果が得られなくなってしまいます。

対応方法

対応方法としては2つあります。

sqlalchemy.sql.expression を使う

sqlalchemy.sql.expressionには、真偽値を表すsqlalchemy.sql.expression.true()sqlalchemy.sql.expression.false()が用意されています。

これを利用して以下のようにコードを修正する方法です。

from sqlalchemy.sql.expression import false

users = session.query(User).filter(User.deleted == false())

sqlalchemy.sql.operators.ColumnOperators を使う

もう1つはsqlalchemy.sql.operators.ColumnOperatorsに用意されている比較用のメソッドis_(other)isnot(other)を利用する方法です。

こちらの場合は以下のようになります。

users = session.query(User).filter(User.deleted.is_(False))

これで、flake8のE712エラーは出なくなります。

まとめ

以上、flake8利用時にSQLAlchemyでBoolean型のフィルタを掛けるときの注意点でした。私はうっかりflake8に言われるがままに修正してしまい想定外の挙動にしてしまいました。お気をつけください!

どなたかのお役に立てば幸いです。それでは!

参考