2

ID のみを使用して Pydantic オブジェクトを構築し、ID に基づいて他のフィールドに入力したいと考えています。
バリデータとポストイニシャルの2つの異なるアプローチを試しました。どちらもうまくいきませんでした。

共通コード:

from pydantic import BaseModel, validator

obj_list = [
    {'id': 1, 'name': 'a', 'desc': 'desc1'},
    {'id': 2, 'name': 'b', 'desc': 'desc2'},
    {'id': 3, 'name': 'c', 'desc': 'desc3'}
]

解決策 1:

class Obj(BaseModel):
    id: int
    name: str = None
    desc: str = None

    @validator('id')
    def validate_exists(cls, v):
        items = [h for h in obj_list if h['id'] == v]
        if len(items) == 0:
            raise ValueError('id doesnt exist')
        return v

    def __post_init__(self):
        item = [h for h in obj_list if h['name'] == v][0]
        self.name = item['name']
        self.desc = item['desc']

Obj(id=1)
# <Obj id=1 name=None desc=None>

解決策 2:

class Obj(BaseModel):
    name: str = None
    desc: str = None
    id: int

    @validator('id')
    def validate_exists(cls, v, values):
        items = [h for h in obj_list if h['id'] == v]
        if len(items) == 0:
            raise ValueError('id doesnt exist')
        item = items[0]
        values['name'] = item['name']
        values['desc'] = item['desc']
        return v

Obj(id=1)
# <Obj name=None desc=None id=1>

出来そうな気がします。Pydantic と FastApi の両方のドキュメントを読みましたが、これに関連するものは見つかりませんでした。では、ID のみを使用してオブジェクトを作成し、DB または別のオブジェクトを使用してフィールドに入力するにはどうすればよいでしょうか?

4

2 に答える 2

1

__post_init__存在しません。データクラスと混同されていると思います。

モデルオブジェクトを作成するときに、ピダンティックなものの検証が1回発生する必要があります。を使用してこれを回避できますがConfig.validate_assignment

これには 2 つの解決策があります。

  1. 各モデルを作成してidから、属性の割り当てを使用して他のフィールドを設定します。これは遅くなり、間違ったアプローチだと思います。
  2. モデルの作成に必要なすべてのデータが揃うまで、モデルを作成しないでください。これが最良のアプローチであることをお勧めします。
于 2020-03-15T22:33:46.023 に答える