🔦
Pydanticがわからないのでメモる2
概要
前回のpydanticのメモでおおよそ使い方に困らないだろうと思っていたら舌の根も乾かぬうちに実装方法がわからないバリデーションパターンに遭遇した。フィールド間の関係性に関する制約はどう設定するのだろうか?
対象クラスと設定したいルール
2つのboolフィールドを持つクラス
class Flags(BaseModel):
is_flip: bool = True
is_zoom: bool = True
すべてのフィールドがFalseの場合ValueError
2つの属性を持つFlagsのオブジェクトを作成する際に少なくとも1つはTrueでなくてはならない、というルールを設定したい。
is_flip | is_zoom | Validation result |
---|---|---|
False | False | raise ValueError |
False | True | OK |
True | False | OK |
True | True | OK |
pydantic.model_validatorを使う
フィールドは特に手を加える必要なく、バリデーション関数を追加するのみでルールの追加は完了。
ところでfield_validatorやその他フィールド単位のルールが設定されている場合だと、model_validatorアノテーションが付加された関数はいつ動作するのか?
field_validatorとmodel_validatorの呼び出し順
確認用コード
動作結果
fv() v:is_flip
fv() v:is_zoom
validatorf2d() called.
f2d:is_flip=True is_zoom=True
呼び出し順は
- is_flipのfield_validator
- is_zoomのfield_validator
- model_validator
という結果になった。
フィールドの確認順序はコンストラクタで指定した順番だろうか?という疑問を挙げてみたもののフィールドのバリデーション実行順番が問題になることはない(問題になるようなバリデーションはmodel_validatorで処理するべきでは?)と思うのでスルーする。
また、model_validatorのmode='before'は公式ドキュメントにBecause of this mode='before' validators are extremely flexible and powerful but can be cumbersome and error prone to implement.
[1]と記載されており、この意見に同意のため必要となる特殊な状況下に遭遇しない限りは使わないことにする。
model_validatorによる動作確認
結果
....
----------------------------------------------------------------------
Ran 4 tests in 0.001s
OK
前回記事
参考
Discussion