Open5
Pydantic を調べて使ってみる-1

FastAPI でSQLModel を使ってるので Pydantic について知ろうと思ってまとめる
- Pydantic はバリデーションとシリアライズ(JSON と Python オブジェクトの変換)、型定義を担当
- SQLAlchemy は ORM
- SQLModel が上記 2 つを組み合わせて、1つのモデルを定義することで、DBとのやり取りと API のデータバリデーションなどをできるようにしている

-
Pydantic は Python のための「型ヒントベースのデータバリデーションとシリアライズライブラリ」
- 型ヒントを活用して、 データの構造や型の正しさを検証(validate) できる
-
※ FastAPI で使ってるから調べて見たが、FastAPI の ORM が sqlmodel で、こいつが Pydantic に依存してる
- ただし、sqlmodel の依存してる Pydantic は V1 系で、最新の Pydantic は V2 系となっていて変わっていると 🤔
- 使えるバージョンを見たら上記は間違ってそうで、1系も使えるけど、2.2.0 以降は使えそう

用語整理
- schema: データ構造
- Model: 構造化されたデータの設計図(スキーマ) を表すクラスで、
BaseModel
を継承したもの

サンプル
from pydantic import BaseModel, ConfigDict
class User(BaseModel):
id: int
name: str = 'Jane Doe'
model_config = ConfigDict(str_max_length=10)
user インスタンス作成
user = User(id='123')
assert user.name == 'Jane Doe' # デフォルトで設定してる
assert user.id == 123
assert isinstance(user.id, int)
model_dump() で dict(辞書型) に出せる
dict(user) でも出せるが、入れ子になった場合に出力してくれない
assert user.model_dump() == {'id': 123, 'name': 'Jane Doe'}
その他、いかにいろいろとメソッドとかありそう
Model で定義した方に強制的に cast される
strict mode があって、それだと変換してくれない
コレクション型は list や dict のような具体的な型を使うべき
from pydantic import BaseModel
class Model(BaseModel):
a: int
b: float
c: str
print(Model(a=3.000, b='2.72', c=b'binary data').model_dump())
#> {'a': 3, 'b': 2.72, 'c': 'binary data'}
extra data(上記例なら Model(a=3.000, b='2.72', c=b'binary data', d='extra_data') みたいな d を入れた場合、エラーにはならないし、インスタンスにも保存しない
model_config = ConfigDict(extra='allow') を設定すると保持するようになる
allow 以外のオプションは以下
- ignore: 余分なものは無視する: これがデフォルト
- forbid: 余計なものを禁止する
class Model(BaseModel):
x: int
model_config = ConfigDict(extra='allow')
m = Model(x=1, y='a')
assert m.model_dump() == {'x': 1, 'y': 'a'}
assert m.__pydantic_extra__ == {'y': 'a'}

いろいろ見ていこうと思ったけど、先に SQLModel を見るべきなので、一旦ここまで