Traffine I/O

日本語

2023-03-13

Pydanticバリデータのeach_itemフラグ

Pydanticバリデータのeach_itemフラグについて

each_itemフラグは、Pydanticバリデータの機能の一つで、Trueに設定することで、入力データ内のイテラブル(例えばリストや辞書)の各アイテムに定義されたバリデーションルールを適用することができます。

each_itemフラグの実装

each_itemフラグを使用するには、Pydanticライブラリからvalidatorデコレータをインポートし、バリデーション関数を定義して、each_item=Trueに設定します。バリデーション関数は、フィールド名、フィールド値、およびモデルインスタンスの値を受け取り、指定された基準を満たさない場合はバリデーションエラーを発生させるか、検証された値を返します。

以下は例です。

python
from pydantic import BaseModel, validator

class PositiveNumberList(BaseModel):
    numbers: List[int]

    @validator('numbers', each_item=True)
    def validate_positive(cls, item):
        if item < 0:
            raise ValueError('Item must be a positive integer')
        return item

この例では、PositiveNumberListモデルを定義し、数値のリストを受け取るnumbersフィールドがあります。また、数値フィールドに対するバリデータを作成し、各アイテムが正の整数であることを確認します。each_item=Trueを設定することで、バリデータはリスト内の各アイテムに対してvalidate_positive関数を適用します。

よくあるミスと解決策

each_itemフラグを使用する場合、イテラブル内の各アイテムに対してバリデータが適用されることを覚えておくことが重要です。よくある間違いは、バリデーションロジックを個々のアイテムではなく、イテラブル全体に適用することです。これを避けるためには、関数内のバリデーションロジックが個々のアイテムに適用されるように設計する必要があります。

例えば、以下の誤った実装を考えてみます。

python
from pydantic import BaseModel, validator

class IncorrectPositiveNumberList(BaseModel):
    numbers: List[int]

    @validator('numbers', each_item=True)
    def validate_positive(cls, numbers):
        for number in numbers:
            if number < 0:
                raise ValueError('All items must be positive integers')
        return numbers

この場合、バリデータ関数validate_positiveは、関数内でnumbersイテラブルを誤ってループ処理していますが、すでにeach_item=Trueフラグが各アイテムに対して関数を適用しています。そのため、関数は整数を期待しているのにリストを受け取ってしまい、TypeErrorが発生します。

この問題を解決するには、関数を個々のアイテムに適用するように書き直します。

python
from pydantic import BaseModel, validator

class CorrectPositiveNumberList(BaseModel):
    numbers: List[int]

    @validator('numbers', each_item=True)
    def validate_positive(cls, number):
        if number < 0:
            raise ValueError('Item must be a positive integer')
        return number

この場合、validate_positive関数はnumbersリスト内の各アイテムに正しく適用され、各数値が正の整数であることが保証されます。

参考

https://docs.pydantic.dev/usage/validators/

Ryusei Kakujo

researchgatelinkedingithub

Focusing on data science for mobility

Bench Press 100kg!