PyMongo传递JSON至函数报错的原因与简便解决方法
MongoDB插入JSON数据报错原因及解决方法
之前尝试将JSON数据传入Python函数存入MongoDB,先后遇到两个报错:
- 使用
json.dumps()转字符串传入,再用json.loads()解析时出现JSONDecodeError - 直接传入JSON格式列表时出现
TypeError: document must be an instance of dict...
第一段代码及报错分析
代码
import pymongo import datetime import json myclient = pymongo.MongoClient("mongodb://localhost:27017/users") def Create_DB_save_data(input_new_DB_name, input_new_collection_name, input_json_inStr_list): mydb_Name= input_new_DB_name mydb = myclient[mydb_Name] existing_DB = myclient.list_database_names() dblist = myclient.list_database_names() if mydb_Name in dblist: boolean_db_exist = True mycol = mydb["input_new_collection_name"] # 错误:硬编码集合名,未使用用户输入变量 existing_collection = mydb.list_collection_names() collist = mydb.list_collection_names() if "input_new_collection_name" in collist: # 错误:判断固定字符串而非用户输入的集合名 boolean_collection_exist = True json_input_end = json.loads(input_json_inStr_list) x = mycol.insert_many(json_input_end) Inserted_data = x.inserted_ids return existing_DB, existing_collection, Inserted_data input_new_DB_name = input("Enter ur new DB name: ") input_new_collection_name = input("Enter ur new collection name: ") input_json = input("Enter the json input: ") input_json_inStr_list = json.dumps(input_json) # 多余操作:input_json已是字符串,再次dumps会转义内容 # 错误:调用函数时传入原始input_json,而非处理后的input_json_inStr_list list_of_DB ,list_of_collection, new_insert_data = Create_DB_save_data(input_new_DB_name, input_new_collection_name, input_json) print(list_of_DB) print(list_of_collection) print(new_insert_data)
输入内容
Enter ur new DB name: 111112333 Enter ur new collection name: wwfsvdf Enter the json input: [{"name": "Joy", "ID": "000111", "Age": 23 , "time" : json_datetime},{ "name": "Tom", "ID": "000222", "Age": 88, "time" : json_datetime} ]
报错核心原因
- 输入的JSON包含
json_datetime,这是Python变量,不属于合法JSON值(JSON仅支持字符串、数字、布尔、数组、对象、null),解析时无法识别 - 函数调用传参错误:生成了
input_json_inStr_list却未传入,反而传了原始字符串;且json.dumps(input_json)会把用户输入的字符串再次转义(如双引号变成\"),导致解析失败 - 集合名硬编码,未使用用户输入的
input_new_collection_name变量
第二段代码及报错分析
代码
import pymongo import datetime import json myclient = pymongo.MongoClient("mongodb://localhost:27017/users") def Create_DB_save_data(input_new_DB_name, input_new_collection_name, input_json): mydb_Name= input_new_DB_name mydb = myclient[mydb_Name] existing_DB = myclient.list_database_names() dblist = myclient.list_database_names() if mydb_Name in dblist: boolean_db_exist = True mycol = mydb["input_new_collection_name"] # 同样的集合名硬编码错误 existing_collection = mydb.list_collection_names() collist = mydb.list_collection_names() if "input_new_collection_name" in collist: # 同样的判断错误 boolean_collection_exist = True My_list = [] My_list.append(input_json) # 错误:input_json是字符串,不是字典,不符合insert_many要求 x = mycol.insert_many(My_list) Inserted_data = x.inserted_ids return existing_DB, existing_collection, Inserted_data input_new_DB_name = input("Enter ur new DB name: ") input_new_collection_name = input("Enter ur new collection name: ") input_json = input("Enter the json input: ") list_of_DB ,list_of_collection, new_insert_data = Create_DB_save_data(input_new_DB_name, input_new_collection_name, input_json) print(list_of_DB) print(list_of_collection) print(new_insert_data)
报错核心原因
input_json是用户输入的字符串,不是Python字典对象,insert_many要求传入字典/BSON对象的迭代器,直接传入字符串会触发类型校验失败- 同样存在集合名硬编码的问题
简便解决方法
- 修正输入JSON格式:把
json_datetime替换为合法JSON值(如ISO日期字符串"2024-05-20T12:00:00"),或在代码中替换为Pythondatetime对象 - 正确解析输入字符串:用
json.loads()把输入字符串转成Python字典列表,再传给insert_many - 修复集合名硬编码:使用变量
input_new_collection_name而非固定字符串 - 移除多余操作:删除不必要的
json.dumps()调用
修正后的完整代码
import pymongo import datetime import json myclient = pymongo.MongoClient("mongodb://localhost:27017/users") def Create_DB_save_data(input_new_DB_name, input_new_collection_name, input_json_str): # 获取数据库与集合(使用用户输入的名称) mydb = myclient[input_new_DB_name] mycol = mydb[input_new_collection_name] # 解析JSON字符串,将标记的json_datetime替换为当前时间 json_data = json.loads(input_json_str) for item in json_data: if "time" in item and item["time"] == "json_datetime": item["time"] = datetime.datetime.now() # 插入数据并返回结果 x = mycol.insert_many(json_data) return myclient.list_database_names(), mydb.list_collection_names(), x.inserted_ids input_new_DB_name = input("Enter ur new DB name: ") input_new_collection_name = input("Enter ur new collection name: ") # 输入时将json_datetime改为字符串形式 input_json_str = input("Enter the json input: ") list_of_DB, list_of_collection, new_insert_data = Create_DB_save_data(input_new_DB_name, input_new_collection_name, input_json_str) print(list_of_DB) print(list_of_collection) print(new_insert_data)
输入示例
Enter ur new DB name: 111112333 Enter ur new collection name: wwfsvdf Enter the json input: [{"name": "Joy", "ID": "000111", "Age": 23 , "time" : "json_datetime"},{"name": "Tom", "ID": "000222", "Age": 88, "time" : "json_datetime"} ]
额外说明
- MongoDB的
insert_many可直接接受Python字典列表,无需转成JSON字符串再解析,只要确保数据是合法字典结构 - 处理日期时,建议在Python代码中生成
datetime对象,MongoDB会自动存储为BSON日期类型,方便后续查询
内容的提问来源于stack exchange,提问作者j ton
相关产品推荐
相关产品推荐

