Pyndantic v2 を前提とします。
仮想環境を作成します。
uv venv --python 3.13
source .venv/bin/activatepip コマンドでインストールします。
uv pip install pydanticREPL を起動させます。
pythonモジュールおよびデータクラスを作成します。
from pydantic import BaseModel
class User(BaseModel):
id: int
name: str
u = User(id=1, name="Alice")まずはデータクラスの中身を調べてみましょう。e
uUser(id=1, name='Alice')
別のデータクラスを作成してみましょう。id に文字列としての数字を投入します。
User(id="1", name="Bob")結果は自動的に数値に変換されます。
User(id=1, name='Bob')今度は id に数字ではない文字列を投入します。
User(id="abc", name="Carol")Traceback (most recent call last):
File "<python-input-5>", line 1, in <module>
User(id="abc", name="Carol")
~~~~^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/masakielastic/pydantic-project/.venv/lib/python3.13/site-packages/pydantic/main.py", line 250, in __init__
validated_self = self.__pydantic_validator__.validate_python(data, self_instance=self)
pydantic_core._pydantic_core.ValidationError: 1 validation error for User
id
Input should be a valid integer, unable to parse string as an integer [type=int_parsing, input_value='abc', input_type=str]
For further information visit https://errors.pydantic.dev/2.12/v/int_parsingu = User(id=1, name="Alice")u.model_dump(){'id': 1, 'name': 'Alice'}
u.model_dump_json()'{"id":1,"name":"Alice"}'
from typing import Optional
class Item(BaseModel):
title: str
price: float = 0.0
memo: Optional[str] = NoneItem(title="Book")Item(title='Book', price=0.0, memo=None)class Point(BaseModel):
x: float
y: floatpoints = [Point(x=i, y=i**2) for i in range(5)]
points[Point(x=0.0, y=0.0), Point(x=1.0, y=1.0), Point(x=2.0, y=4.0), Point(x=3.0, y=9.0), Point(x=4.0, y=16.0)]class Address(BaseModel):
city: str
class Person(BaseModel):
name: str
address: Addressp = Person(name="Alice", address={"city": "Tokyo"})
pfrom pydantic import BaseModel, field_validator
class Product(BaseModel):
name: str
price: float
@field_validator("price")
def check_price(cls, v):
if v < 0:
raise ValueError("negative!")
return v正の値を投入してみます。
Product(name="Tea", price=200)負の値を投入するとエラーになります。
Product(name="Tea", price=-100)Traceback (most recent call last):
File "<python-input-21>", line 1, in <module>
Product(name="Tea", price=-199)
~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/masakielastic/pydantic-project/.venv/lib/python3.13/site-packages/pydantic/main.py", line 250, in __init__
validated_self = self.__pydantic_validator__.validate_python(data, self_instance=self)
pydantic_core._pydantic_core.ValidationError: 1 validation error for Product
price
Value error, negative! [type=value_error, input_value=-199, input_type=int]
For further information visit https://errors.pydantic.dev/2.12/v/value_errorfrom pydantic import BaseModel
class User(BaseModel):
id: int
name: str
json_str = '{"id": 1, "name": "Alice"}'json_str = '{"id": 1, "name": "Alice"}'
u = User.model_validate_json(json_str)u の中身を見ています。
u型を調べてみます。
type(u))
<class '__main__.User'>
JSON を辞書に変換してからデータクラスに投入する方法を試してみます。
import json
from pydantic import BaseModel
class User(BaseModel):
id: int
name: str
json_str = '{"id": "1", "name": "Bob"}'data = json.loads(json_str)
u = User.model_validate(data)
u不正な値が投入された場合をチェックしてみます。
from pydantic import BaseModel, ValidationError
class User(BaseModel):
id: int
name: str
try:
User.model_validate_json('{"id": "abc", "name": "Alice"}')
except ValidationError as e:
print(e)結果です。
1 validation error for User
id
Input should be a valid integer, unable to parse string as an integer [type=int_parsing, input_value='abc', input_type=str]
For further information visit https://errors.pydantic.dev/2.12/v/int_parsing
from pydantic import BaseModel
class User(BaseModel):
id: int
name: strschema = User.model_json_schema()
schema出力例
{
'title': 'User',
'type': 'object',
'properties': {
'id': {'title': 'Id', 'type': 'integer'},
'name': {'title': 'Name', 'type': 'string'}
},
'required': ['id', 'name']
}JSON として保存するには json_dump を使います。
schema_json = json.dumps(schema, indent=2)
schema_json
'{\n "properties": {\n "id": {\n "title": "Id",\n "type": "integer"\n },\n "name": {\n "title": "Name",\n "type": "string"\n }\n },\n "required": [\n "id",\n "name"\n ],\n "title": "User",\n "type": "object"\n}'
JSON スキーマをファイルに保存する。
import json
with open("schema.json", "w") as f: json.dump(User.model_json_schema(), f, indent=2)
例外
----
```python
from pydantic import BaseModel, ValidationError
class User(BaseModel):
id: int
name: str
try:
User.model_validate({"id": "abc", "name": "Alice"})
except ValidationError as e:
print("ERROR:", e)
結果のエラーです。
ERROR: 1 validation error for User
id
Input should be a valid integer, unable to parse string as an integer [type=int_parsing, input_value='abc', input_type=str]
For further information visit https://errors.pydantic.dev/2.12/v/int_parsing
JSON 形式でエラーを出力させることもできます。
try:
User.model_validate({"id": "abc", "name": "Alice"})
except ValidationError as e:
print(e.errors())
デフォルトモードでは型変換が行われます。
class User(BaseModel):
id: int
name: str
u = User.model_validate({"id": "1", "name": 123})
print(u)
print(type(u.id), type(u.name))strict モードでは型変換が認められません。
from pydantic import BaseModel, StrictInt, StrictStr
class User(BaseModel):
id: StrictInt
name: StrictStr
User.model_validate({"id": "1", "name": 123})pydantic_core._pydantic_core.ValidationError: 2 validation errors for User
id
Input should be a valid integer [type=int_type, input_value='1', input_type=str]
For further information visit https://errors.pydantic.dev/2.12/v/int_type
name
Input should be a valid string [type=string_type, input_value=123, input_type=int]
For further information visit https://errors.pydantic.dev/2.12/v/string_type
モデル全体を strict モードにしてみます。
from pydantic import BaseModel
class User(BaseModel):
id: int
name: str
model_config = {
"strict": True
}試してみます。
User.model_validate({"id": "1", "name": "Alice"})uv pip install pytest
import pytest
from pydantic import BaseModel, ValidationError
class User(BaseModel):
id: int
def test_valid():
u = User.model_validate({"id": 1})
assert u.id == 1
def test_invalid():
with pytest.raises(ValidationError):
User.model_validate({"id": "abc"})python -m pytest
==================================================== test session starts =====================================================
platform linux -- Python 3.13.9, pytest-9.0.1, pluggy-1.6.0
rootdir: /home/masakielastic/pydantic-project
collected 2 items
test_validation.py .. [100%]
===================================================== 2 passed in 0.07s ======================================================
(pydantic-project) masakielastic@penguin:~/pydantic-project$ ls