2021年12月9日木曜日

Python の配列や辞書を json_array や json_object に渡す方法

Python の配列や辞書を json_array や json_object に渡す方法

概要

前回 cast を使って Python -> MySQL の型変換をしました
今回は json_array と json_object を使った方法を紹介します

環境

  • macOS 11.6.1
  • MySQL 8.0.26
  • flask-sqlalchemy 2.5.1

サンプルコード

def upsert(self, id, profile):
    """フィールドがない場合は登録します."""
    user_query = User.query.filter(User.id == id)
    for key, value in profile.items():
        if isinstance(value, list):
            # list の場合
            user_query.update(
                {"profile": db.func.json_set(
                    User.profile,
                    "$." + key,
                    db.func.json_array(*value))}, synchronize_session='fetch')  # noqa: E501
            db.session.commit()
        elif isinstance(value, dict):
            # dict の場合
            user_query.update(
                {"profile": db.func.json_set(
                    User.profile,
                    "$." + key,
                    db.func.json_object(*list(itertools.chain.from_iterable(value.items()))))}, synchronize_session='fetch')  # noqa: E501
            db.session.commit()
        else:
            # str や int など構造を持たない値の場合
            user_query.update(
                {"profile": db.func.json_set(
                    User.profile,
                    "$." + key,
                    value)}, synchronize_session='fetch')
            db.session.commit()

解説

json_array や json_object に flatten した値を渡しています
配列の場合はアスタリスク一つで展開できます
辞書の場合は少し面倒で items() でイテレータ情報を取得したあとで itertools.chain.from_iterable で平坦化してあげています

0 件のコメント:

コメントを投稿