跳到内容

数据库

Pydantic 是一个用于定义 ORM(对象关系映射)库模型的出色工具。ORM 用于将对象映射到数据库表,反之亦然。

SQLAlchemy

Pydantic 可以与 SQLAlchemy 配对使用,因为它可用于定义数据库模型的模式。

代码重复

如果您将 Pydantic 与 SQLAlchemy 一起使用,您可能会遇到一些代码重复的困扰。如果您发现自己遇到这种困难,您也可以考虑 SQLModel,它将 Pydantic 与 SQLAlchemy 集成在一起,从而消除了大部分代码重复。

如果您更喜欢将纯 Pydantic 与 SQLAlchemy 一起使用,我们建议将 Pydantic 模型与 SQLAlchemy 模型一起使用,如下例所示。在这种情况下,我们利用 Pydantic 的别名功能来命名 Column,使其与 SQLAlchemy 保留字段同名,从而避免冲突。

import sqlalchemy as sa
from sqlalchemy.orm import declarative_base

from pydantic import BaseModel, ConfigDict, Field


class MyModel(BaseModel):
    model_config = ConfigDict(from_attributes=True)

    metadata: dict[str, str] = Field(alias='metadata_')


Base = declarative_base()


class MyTableModel(Base):
    __tablename__ = 'my_table'
    id = sa.Column('id', sa.Integer, primary_key=True)
    # 'metadata' is reserved by SQLAlchemy, hence the '_'
    metadata_ = sa.Column('metadata', sa.JSON)


sql_model = MyTableModel(metadata_={'key': 'val'}, id=1)
pydantic_model = MyModel.model_validate(sql_model)

print(pydantic_model.model_dump())
#> {'metadata': {'key': 'val'}}
print(pydantic_model.model_dump(by_alias=True))
#> {'metadata_': {'key': 'val'}}

注意

上面的示例之所以有效,是因为别名在字段填充方面优先于字段名称。访问 SQLModelmetadata 属性将导致 ValidationError