■ はじめに
https://dk521123.hatenablog.com/entry/2019/10/19/104805
の続き。 JSONに関して扱うことになったので、メモ。
目次
【1】JSONインスタンスをコピーする 【2】JSONをマージする 【3】JSONオブジェクトをフィルタリングする 【4】SELECTした結果をJSON化 1)PostgreSQLの場合 【5】エラー「TypeError: Object of type datetime is not JSON serializable」対策
【1】JSONインスタンスをコピーする
<json>.copy() を使う
サンプル
import json input_dict = {"name": "Smith", "birth_day": "2002-12-21", "gender": "man"} clone_dict = input_dict.copy() clone_dict["name"] = "Mike" # {'name': 'Smith', 'birth_day': '2002-12-21', 'gender': 'man'} print(input_dict) # {'name': 'Mike', 'birth_day': '2002-12-21', 'gender': 'man'} print(clone_dict)
【2】JSONをマージする
<json1>.update(<json2>) を使う
※ キーが重複する場合
⇒ 引数 <json2> で上書きされる
サンプル
import json input1_dict = {"name": "Smith", "birth_day": "1967-08-11", "gender": "man"} input2_dict = {"birth_day": "2012-12-23", "occupation": "IT", "note": "Hello world"} input1_dict.update(input2_dict) # {'name': 'Smith', 'birth_day': '2012-12-23', 'gender': 'man', 'occupation': 'IT', 'note': 'Hello world'} print(input1_dict)
【3】JSONオブジェクトをフィルタリングする
* lambda / filter を使うといいかも。
https://stackoverflow.com/questions/40827356/find-a-value-in-json-using-python/40827383
サンプル
例1:lambda / filterでフィルタリング
user_list = [ { "id": "X0001", "name": "Mike", "birth_date": None }, { "id": "X0002", "name": "Tom", "birth_date": "2022-01-01" }, { "id": "X0003", "name": "Paul", "birth_date": "1988-12-12" } ] results = list(filter(lambda x: x["id"] == "X0003", user_list)) # [{'id': 'X0003', 'name': 'Paul', 'birth_date': '1988-12-12'}] print(results)
例2:汎用的に使えるように関数化
def find(target_list: list, filter_dict: dict): return_values = target_list for key, value in filter_dict.items(): return_values = list(filter(lambda x: x[key] == value, return_values)) return return_values user_list = [ { "id": "X0001", "name": "Mike", "birth_date": None }, { "id": "X0002", "name": "Tom", "birth_date": "2022-01-01" }, { "id": "X0003", "name": "Paul", "birth_date": "1988-12-12" }, { "id": "X0004", "name": "Mike", "birth_date": "1988-12-12" }, { "id": "X0005", "name": "Paul", "birth_date": "1988-12-12" }, ] results = find(user_list, {"name": "Mike", "birth_date": "1988-12-12"}) # [{'id': 'X0004', 'name': 'Mike', 'birth_date': '1988-12-12'}] print(results)
【4】SELECTした結果をJSON化
1)PostgreSQLの場合
* 以下の関連記事を参照のこと
Python で PostgreSQL を使う ~ psycopg2編 ~
https://dk521123.hatenablog.com/entry/2020/05/06/141029
【5】エラー「TypeError: Object of type datetime is not JSON serializable」対策
* 以下のコードを実行するとエラー
エラーが発生するコード
import json from datetime import datetime now = datetime.now() input_json = { "created_at": now, "user": "Mike" } print(json.dumps(input_json))
エラー詳細
TypeError: Object of type datetime is not JSON serializable
解決案
* 以下が参考になった
https://sebhastian.com/object-of-type-datetime-is-not-json-serializable/
https://www.bioerrorlog.work/entry/python-datetime-not-json-serializable-error
案1:default=strを付与
print(json.dumps(input_json, default=str)) # {"created_at": "2023-10-31 20:07:54.386454", "user": "Mike"}
案2:datetime => string に変換
now = datetime.now().strftime("%Y-%m-%d") print(json.dumps(input_json) # {"created_at": "2023-10-31", "user": "Mike"}
案3:カスタム変換をかませる
import json from datetime import date, datetime def custom_json_serial(obj): if isinstance(obj, (datetime, date)): return obj.isoformat() raise TypeError (f'Type {obj} not serializable') now = datetime.now() input_json = { "created_at": now, "user": "Mike" } print(json.dumps(input_json, default=custom_json_serial)) # {"created_at": "2023-10-31T20:14:36.145797", "user": "Mike"}
関連記事
Python ~ 基本編 / 文字列 ~
https://dk521123.hatenablog.com/entry/2019/10/12/075251
Python ~ 基本編 / JSON ~
https://dk521123.hatenablog.com/entry/2019/10/19/104805
Python ~ 基本編 / YAML ~
https://dk521123.hatenablog.com/entry/2019/10/16/225401
Python ~ 基本編 / ラムダ lambda ~
https://dk521123.hatenablog.com/entry/2019/09/23/000000
Python ~ 基本編 / map ~
https://dk521123.hatenablog.com/entry/2021/03/29/000000
Python ~ 基本編 / 辞書 ~
https://dk521123.hatenablog.com/entry/2019/10/27/100014
Python ~ 基本編 / 辞書・あれこれ ~
https://dk521123.hatenablog.com/entry/2020/10/11/000000
Python で PostgreSQL を使う ~ psycopg2編 ~
https://dk521123.hatenablog.com/entry/2020/05/06/141029
Pandas ~ 基本編 / JSON編 ~
https://dk521123.hatenablog.com/entry/2022/02/16/000000
Python ~ ndjson を扱う ~
https://dk521123.hatenablog.com/entry/2022/08/30/224248