はじめに
Python の“最強データモデル”を使いこなす
Python で「外部データを安全に扱う」ことほど難しい作業はない。
文字列の "10" を int にしたり、null を許可したり、形式をチェックしたり…
全部手書きするとバグの温床になる。
そこで登場するのが Pydantic。
FastAPI の心臓でもある、Python のデータバリデーション王者です。
このガイドでは、初心者でも実践レベルに到達できるよう
Pydantic の設計思想 → 実用例 → 応用テクニックまでぜんぶまとめます。
Pydantic とは?
Pydantic は 型注釈(type hints)を使ってデータモデルを定義し、
自動でバリデーション・変換(coercion)・エラー生成をしてくれるライブラリ。
特徴をひとことで言うと:
「Python で JSON / リクエストデータ / 設定ファイルを扱うための最適解」
- データ検証が自動
- 型変換も自動
- 非常に高速(v2 は Rust の
pydantic-coreベース) - FastAPI と最強コンビ
基本の書き方
Model 定義
from pydantic import BaseModel
class User(BaseModel):
id: int
name: str
自動変換(coercion)
u = User(id="10", name="Anna")
print(u.id) # → 10(int に変換)
Pydantic の「強いところ」はここ。
受け取った値を“望ましい形”に勝手に変換してくれる。
バリデーションも自動
型通りでなければエラーにしてくれる:
User(id="hello", name="Anna")
ValidationError
- id: Input should be a valid integer
手動で try/except 祭りをする必要がなくなる。
JSON や dict の変換が最強
dict → モデル
data = {"id": 1, "name": "Anna"}
user = User.model_validate(data)
JSON → モデル
json_str = '{"id": 1, "name": "Anna"}'
user = User.model_validate_json(json_str)
モデル → dict
user.model_dump()
モデル → JSON
user.model_dump_json()
Optional, default, validators
Optional / Union
class User(BaseModel):
id: int
nickname: str | None = None
バリデーション(field_validator)
Pydantic v2 では validator が刷新されて、とても書きやすくなった。
from pydantic import field_validator
class Product(BaseModel):
price: float
@field_validator("price")
def check_price(cls, v):
if v < 0:
raise ValueError("Price must be >= 0")
return v
モデルのネスト(FastAPI で大活躍)
class Address(BaseModel):
city: str
zip: str
class User(BaseModel):
id: int
name: str
address: Address
JSON を入れると自動でネストモデルへ変換される:
User(
id=1,
name="Anna",
address={"city": "Tokyo", "zip": "100-0001"}
)
モデル設定(model_config)
Immutable(不変)にする
class Config(BaseModel):
x: int
y: int
model_config = {
"frozen": True
}
Strict モード(型の厳格化)
class User(BaseModel):
id: int
model_config = {
"strict": True
}
User(id="10") # ❌ エラー(変換も許可しない)
パフォーマンスがエグい(v2)
Pydantic v2 は内部が全部 Rust で書き直されていて速い。
簡易比較:
| 処理 | Pydantic v1 | Pydantic v2 |
|---|---|---|
| Validation | 遅い | 約 5〜10倍速い |
| JSONパース | 普通 | かなり速い |
| Model生成 | 重い | dataclass に近いレベル |
“Web API のデータ処理”レベルならもう最強。
実践編:設定ファイル(Settings 管理)
Pydantic は読み込みとバリデーションが強いから設定管理に向いてる。
from pydantic import BaseModel, Field
class Settings(BaseModel):
host: str = Field(default="localhost")
port: int = Field(default=8000)
.env も読み込める(pydantic-settings)
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
api_key: str
debug: bool = False
実践編:FastAPI と組み合わせると無双
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class User(BaseModel):
id: int
name: str
@app.post("/users")
def create(user: User):
return user
FastAPI はリクエスト JSON を
→ 自動で Pydantic モデルに変換
→ 自動で型チェック
→ エラーメッセージも自動生成
これだけでバックエンド 8 割終わるレベルで便利。
アンチパターン
❌ BaseModel を巨大クラスにしない
Pydantic は データモデル。
ビジネスロジックを込みにするとテストも設計も崩れる。
❌ dataclass と混ぜて意味不明な構造にしない
API に Pydantic
内部ロジックに dataclass
が正しい使い分け。
❌ 複雑な継承地獄
Pydantic モデルは合成(composition)のほうが圧倒的に安全。
まとめ
✔ 型ヒントを使った強力なデータモデル
✔ バリデーションが自動
✔ JSON 入出力が最強
✔ FastAPI との連携が神
✔ 設定・環境変数読み込みにも使える
✔ Rust コアでとても速い(v2)