概要
前回 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 件のコメント:
コメントを投稿