query_propertyとhybrid_property(hybrid_method)が便利。

機能について

query_property

query_propertyは、モデル*1クラスが検索クエリをあたかもpropertyであるかのように持たせることができる機能。以下が利用例。

query_propertyを利用しない場合の検索は以下のようになる。

# e.g. User.first_nameで絞り込み検索
session.query(User).filter(User.name == "foo").one()

これがquery_propertyを使うと*2以下のように書ける。

# e.g. User.first_nameで絞り込み検索
User.query.filter(User.name == "foo").one()

ということは、検索クエリを用いたメソッドをモデルに直接書けるということになる。

hybrid_property(hybrid_method)

hybrid_propertyはクラスとインスタンスに紐付く*3のフィールドへのアクセスとして便利な機能を提供するもの。
クラス/インスタンスでの機能は以下の通り

caller 機能
クラス 条件式の指定(e.g. filter(User.name == "foo"))
インスタンス フィールドから値を取得(e.g. user.name)

通常のpropertyと何が違うのかと言えば、定義したメソッド(プロパティ)をひとつのフィールドのようにして扱えること。
例えば、以下のようなUserモデルがあるとする。

  • first_name, last_nameというフィールドを持つ
  • get_full_name()により、フルネームを文字列で取得できる

このようなモデルを定義したとき、get_full_name()の戻り値を元に絞り込み検索を行いたい。と思うことがあると思う。
このような時には、hybrid_propertyを利用すると良い。

上記のUserモデルにfullnameというhybrid_propertyを生やした場合には、以下のようにして使うことができる。(ただし、Userモデルのテーブルにfullnameというフィールドは存在しない)

user = session.query(User).filter(User.fullname="foobar").one()
print user.fullname

実際に動作するサンプルの比較

実際の利用方法は以下のコードの通り。

  • 初めのファイル(sample2.py)はquery_propertyとhybrid_propertyを使わない場合の例。
  • 2つ目のファイル(sample3.py)は両方の機能を利用した場合の例。


*1:として利用しようとしている

*2:これをquery_property()の返す値をUser.queryに束縛したクラスを使うと

*3:とされる