🐠

【Python】ネストされたdictをdaciteを用いてdataclassに変換する

に公開

概要

dictをdataclassに変換する際、標準の機能だとPython3: dict を dataclass に変換するで紹介されている通り、辞書のアンパック機能を使う方法が挙げられます。ただ、標準の機能だとネストされたdictには対応できていないようです。
ネストされたdictやjsonからdataclassを作成したいならpydanticが便利の記事に紹介されている通り、Pydanticを導入するのも一つの手ではありますが、Pydanticを導入せずにピンポイントで簡単に変換できる方法はないかなと少し調べてみました。

対応案

How to create a dataclass that handles nested dicts with different names?のstackoverflowの記事に、いくつか方法が挙げられています。daciteというライブラリを使う方法が良いかなと思ったので、今回これを試してみました。

前提

  • 使用したPythonのバージョンは3.13.0です。
  • 使用したdaciteのバージョンは1.8.1a0です。

実装サンプル

以下の通り、変換後のdataclassを定義します。

@dataclass
class PostUrlInfo:
    title: str
    image_url: str | None
    site_name: str | None

@dataclass
class PostUrl:
    url: str
    url_type: str
    url_info: PostUrlInfo | None

@dataclass
class PostPlaceQueryServiceModel:
    _id: str
    user_id: str | None
    name: str
    url: str | None = None
    address: str | None = None
    detail: str | None = None

@dataclass
class PostPlaceQueryServiceModel:
    _id: str
    user_id: str | None
    name: str
    url: str | None = None
    address: str | None = None
    detail: str | None = None

@dataclass
class PostQueryServiceModel:
    id: str
    user_id: str
    title: str
    place: PostPlaceQueryServiceModel
    visited_date: datetime.datetime
    post_date: datetime.datetime
    url_list: List[PostUrl]

最終的にはdictから上記のPostQueryServiceModelに変換を行いたいです。
daciteを使用して、変換を行う処理は以下の通りとなります。

from typing import Dict, List
from dacite import from_dict

def convert_to_dataclass(post_dict: Dict) -> PostQueryServiceModel:
    return from_dict(data_class=PostQueryServiceModel, data=post_dict)

Discussion