Traffine I/O

日本語

2023-03-12

Pydanticモデルと辞書の変換

Pydanticモデルを辞書に変換する

Pydanticの主な機能の1つは、モデルを辞書などのPythonネイティブデータ型に変換する能力です。このプロセスは簡単で、必要に応じてカスタマイズすることができます。この変換を実現するための主な方法は、各Pydanticモデルインスタンスに利用可能な.dict()メソッドを使用することです。

.dict()メソッドの使用

.dict()メソッドは、モデルの辞書表現を返すPydanticモデルの組み込み関数です。このメソッドは、モデルのフィールドを反復処理し、キーがフィールド名に対応し、値がフィールド値に対応する辞書を構築します。

次のPydanticモデルを考えてみます。

python
from pydantic import BaseModel

class User(BaseModel):
    name: str
    age: int
    email: str

このモデルのインスタンスを作成し、辞書に変換することができます。

python
user = User(name='John Doe', age=30, email='john.doe@example.com')
user_dict = user.dict()
print(user_dict)

出力は次のようになります。

{'name': 'John Doe', 'age': 30, 'email': 'john.doe@example.com'}

変換のカスタマイズ

.dict()メソッドには、結果の辞書をカスタマイズするためのいくつかのパラメータがあります。ここでは、これらのパラメータについて詳しく説明し、いくつかの例を示します。

include

このパラメータを使用すると、出力に含めるフィールドのセットを指定できます。その他の全てのフィールドは除外されます。フィールドは、セット内の文字列として渡されます。

python
user_dict = user.dict(include={"name", "email"})
print(user_dict)
{'name': 'John Doe', 'email': 'john.doe@example.com'}

exclude

excludeパラメータを使用すると、出力から除外するフィールドのセットを指定できます。その他の全てのフィールドは含まれます。includeと同様に、フィールドはセット内の文字列として渡されます。

python
user_dict = user.dict(exclude={"email"})
print(user_dict)
{'name': 'John Doe', 'age': 30}

by_alias

by_aliasパラメータをTrueに設定すると、出力辞書がフィールドのエイリアス(定義されている場合)を使用するようになり、フィールド名を使用しなくなります。これは、APIレスポンスを生成する場合など、辞書のキーをモデルの外部表現と一致させたい場合に便利です。

python
from pydantic import BaseModel, Field

class User(BaseModel):
    name: str = Field(alias='username')
    age: int
    email: str

user = User(username='John Doe', age=30, email='john.doe@example.com')
user_dict = user.dict(by_alias=True)
print(user_dict)
{'username': 'John Doe', 'age': 30, 'email': 'john.doe@example.com'}

exclude_unset

exclude_unsetTrueに設定されている場合、モデルインスタンスを作成する際に明示的に設定されていないフィールドは、出力辞書に含まれません。これは、明示的に割り当てられたフィールドのみを含む「スパース」辞書を生成したい場合に便利です。

python
user = User(name='John Doe')
user_dict = user.dict(exclude_unset=True)
print(user_dict)
{'name': 'John Doe'}

exclude_defaults

exclude_defaultsTrueに設定すると、現在デフォルト値に等しいフィールドが出力から除外されます。これは、明示的にデフォルト値以外の値に設定されたフィールドのみを含む辞書を作成したい場合に役立ちます。

python
class User(BaseModel):
    name: str = 'Default Name'
    age: int = 0
    email: str = 'default@example.com'

user = User(name='John Doe', age=30, email='john.doe@example.com')
user_dict = user.dict(exclude_defaults=True)
print(user_dict)
{'name': 'John Doe', 'age': 30, 'email': 'john.doe@example.com'}

exclude_none

exclude_noneTrueに設定すると、値がNoneであるフィールドは出力から除外されます。これは、設定されていないnullableフィールドを無視したい場合に便利です。

python
user = User(name='John Doe', age=None)
user_dict = user.dict(exclude_none=True)
print(user_dict)
{'name': 'John Doe'}

辞書をPydanticモデルに変換

Pydanticモデルはデータの処理と検証を便利に行う方法を提供しますが、APIからのJSONデータや他のPythonライブラリからのデータなど、データが辞書として受け取られることがよくあります。そのような場合には、Pydanticのデータ解析機能を活用して辞書をPydanticモデルに変換することができます。

Pydanticモデルのコンストラクタを使用

辞書をPydanticモデルに変換するもっとも簡単な方法の1つは、モデルのコンストラクタを使用することです。辞書内のキーは、Pydanticモデルで定義された属性に対応する必要があります。

前章で定義されたUserモデルを使用して、辞書を作成してPydanticモデルに変換してみます。

python
user_dict = {'name': 'John Doe', 'age': 30, 'email': 'john.doe@example.com'}

# Convert dictionary to Pydantic model
user = User(**user_dict)

print(user)

出力は次のようになります。

User(name='John Doe', age=30, email='john.doe@example.com')

モデルのコンストラクタでuser_dictの前に**を使用することに注意してください。この演算子は辞書の展開演算子と呼ばれ、辞書内のキーと値を関数にキーワード引数として渡します。

検証エラーの処理

Pydanticモデルの主な機能の1つは、組み込みのデータ検証機能です。辞書からPydanticモデルを作成する際には、Pydanticがデータをモデルの型ヒントに対して検証します。データが予想される型と一致しない場合や、その他のカスタム検証に合格しない場合、PydanticはValidationErrorを発生させます。

例えば、次のように不正なデータ型でUserモデルを作成しようとすると、次のようにValidationErrorが発生します。

python
incorrect_user_dict = {'name': 'John Doe', 'age': '30', 'email': 'john.doe@example.com'}

try:
    user = User(**incorrect_user_dict)
except ValidationError as e:
    print(e)

この場合、Pydanticは、ageフィールドが整数でなければならないことを示すValidationErrorを発生させます。

1 validation error for User
age
  value is not a valid integer (type=type_error.integer)

このエラーメッセージにより、データ検証エラーを効果的にキャッチして処理することができます。

Ryusei Kakujo

researchgatelinkedingithub

Focusing on data science for mobility

Bench Press 100kg!