调用count_documents报错:AttributeError: 'dict'无_txn_read_preference属性
问题分析与解决
错误原因
你调用count_documents时传参方式错误。在PyMongo中,count_documents的第二个参数是session对象,而非查询选项字典。你把{'limit':1}作为第二个位置参数传入,导致PyMongo把这个字典当成了session对象,进而触发AttributeError: 'dict' object has no attribute '_txn_read_preference'错误。
修正方案
方案1:修正count_documents的传参方式
把limit作为关键字参数传入,而非位置参数:
def upsert_load_history(arg_file_type, arg_date, arg_db_collection): print("===== upsert_load_history ======") json_query = {"filetype": arg_file_type} # 用关键字参数传递limit选项 row_count = arg_db_collection.count_documents(json_query, limit=1) if row_count == 0: insert_load_history_new_rows(arg_file_type, arg_date, arg_db_collection) else: update_load_history_for_file_type(arg_file_type, arg_date, arg_db_collection)
方案2:改用find_one更高效判断存在性
既然只是判断文档是否存在,用find_one比count_documents更高效——找到匹配文档就立即返回,无需额外计数操作:
def upsert_load_history(arg_file_type, arg_date, arg_db_collection): print("===== upsert_load_history ======") json_query = {"filetype": arg_file_type} existing_doc = arg_db_collection.find_one(json_query) if not existing_doc: insert_load_history_new_rows(arg_file_type, arg_date, arg_db_collection) else: update_load_history_for_file_type(arg_file_type, arg_date, arg_db_collection)
方案3:用MongoDB原生原子Upsert一步完成(推荐)
MongoDB本身支持原子性的upsert操作,无需先查询再判断,一步完成插入/更新,还能避免并发场景下的竞态问题:
from datetime import datetime def upsert_load_history(arg_file_type, arg_date, arg_db_collection): print("===== upsert_load_history ======") filter_query = {"filetype": arg_file_type} update_data = { "$set": { "last_date_processed": arg_date, "update_date": datetime.utcnow() } } # upsert=True:不存在则插入,存在则更新 arg_db_collection.update_one(filter_query, update_data, upsert=True)
内容的提问来源于stack exchange,提问作者NealWalters
相关产品推荐
相关产品推荐

