如何将含datetime.datetime对象的Mongo嵌套JSON字符串转为字典
解决包含datetime对象的非标准JSON字符串解析问题
你遇到的问题根源是:这个字符串不是标准JSON格式,而是Python字面量格式——用单引号包裹字符串,还包含Python特有的datetime.datetime对象,而json.loads只能解析标准JSON,所以报错。以下是几种可行的解决方法:
方法1:用ast.literal_eval解析(推荐)
ast.literal_eval可以安全解析Python字面量,支持datetime这类内置对象,比eval更安全:
import ast from datetime import datetime raw_str = "[{'actionId': '29df54c0-9f08-4231-8eb2-ca2457003f2d', 'actionName': 'Create a team', 'userActionStatus': 'COMPLETED', 'currentCount': 1, 'targetCount': 1, 'lastActionDate': datetime.datetime(2022, 6, 24, 14, 17, 17, 785000)}]" # 解析为Python列表,lastActionDate直接是datetime对象 parsed_data = ast.literal_eval(raw_str) print(parsed_data[0]['lastActionDate']) # 输出: 2022-06-24 14:17:17.785000
方法2:转换为标准JSON后解析
先把字符串转成符合JSON规范的格式,再用json.loads解析:
- 把单引号替换为双引号;
- 用正则把
datetime.datetime(...)替换为ISO格式的日期字符串; - 解析后可按需转回
datetime对象。
import json import re from datetime import datetime raw_str = "[{'actionId': '29df54c0-9f08-4231-8eb2-ca2457003f2d', 'actionName': 'Create a team', 'userActionStatus': 'COMPLETED', 'currentCount': 1, 'targetCount': 1, 'lastActionDate': datetime.datetime(2022, 6, 24, 14, 17, 17, 785000)}]" # 替换单引号为双引号,符合JSON格式要求 json_compatible_str = raw_str.replace("'", '"') # 正则替换datetime表达式为ISO日期字符串 json_compatible_str = re.sub( r'datetime\.datetime\((\d+), (\d+), (\d+), (\d+), (\d+), (\d+), (\d+)\)', r'"\1-\2-\3T\4:\5:\6.\7Z"', json_compatible_str ) # 解析JSON parsed_data = json.loads(json_compatible_str) # 把日期字符串转回datetime对象 parsed_data[0]['lastActionDate'] = datetime.fromisoformat( parsed_data[0]['lastActionDate'].replace('Z', '') ) print(parsed_data[0]['lastActionDate'])
方法3:直接通过pymongo处理(如果是从Mongo直接查询)
如果是直接用pymongo查询MongoDB数据,不需要手动处理字符串——pymongo会自动把Mongo存储的BSON日期类型转为Python的datetime对象:
from pymongo import MongoClient # 连接MongoDB client = MongoClient('mongodb://localhost:27017/') db = client['你的数据库名'] collection = db['你的集合名'] # 查询文档,直接获取嵌套字段 document = collection.find_one({'_id': '你的文档ID'}) actions = document['你的嵌套字段名'] # actions中的lastActionDate已经是datetime对象 print(actions[0]['lastActionDate'])
内容的提问来源于stack exchange,提问作者James Lee
相关产品推荐
相关产品推荐

