Python操作MongoDB为teams集合添加players子集合报KeyError: '_id'如何解决
问题排查
- 直接原因:你遍历的
x来自本地JSON文件PLClub1819.json,该文件内的俱乐部条目没有预设_id字段,所以访问x["_id"]直接抛出键不存在错误。 - 逻辑问题:你给出的teams集合初始结构为单文档包含整个
clubs数组,而_id是teams集合文档的主键,不是内部clubs数组元素的主键,原有匹配x["_id"]更新的逻辑本身也不成立。
注意:你提到的“子集合”如果是MongoDB层级命名的独立集合,可在下方方案基础上调整写入目标集合即可,嵌入式数组是中小数据量下的更优选择。
解决方案
根据你的使用场景可二选一:
场景1:保持现有teams集合结构(单文档存clubs数组,每个俱乐部下加players数组)
from bson import ObjectId from pymongo import MongoClient import random import json import names client = MongoClient("mongodb://127.0.0.1:27017") db = client.FootballDB teams = db.teams positions = [ 'Goalkeeper', 'Defender', 'Midfielder', 'Striker' ] # 优先读取MongoDB中已有的teams集合数据 team_doc = teams.find_one() if not team_doc: # 若集合为空,先插入本地JSON数据初始化 with open('PLClub1819.json', 'r', encoding='utf-8') as f: data = json.load(f) teams.insert_one(data) team_doc = teams.find_one() for idx, club in enumerate(team_doc['clubs']): players = [] for i in range(15): players.append({ "_id" : ObjectId(), "name" : names.get_full_name(gender='male'), "number" : random.randint(1,30), "position" : random.choice(positions) }) # 通过数组下标定位对应俱乐部,批量写入球员数据 teams.update_one( {"_id": team_doc["_id"]}, {"$set": {f"clubs.{idx}.players": players}} )
场景2:调整teams集合结构(每个俱乐部对应独立文档,更符合MongoDB使用规范)
该结构后续查询、更新单个俱乐部数据效率更高,推荐使用:
from bson import ObjectId from pymongo import MongoClient import random import json import names client = MongoClient("mongodb://127.0.0.1:27017") db = client.FootballDB teams = db.teams positions = [ 'Goalkeeper', 'Defender', 'Midfielder', 'Striker' ] with open('PLClub1819.json', 'r', encoding='utf-8') as f: data = json.load(f) # 清空原有不符合规范的旧数据,可根据需求删除该行 teams.delete_many({}) club_docs = [] for club in data['clubs']: club_doc = { **club, "players": [] } for i in range(15): club_doc["players"].append({ "_id" : ObjectId(), "name" : names.get_full_name(gender='male'), "number" : random.randint(1,30), "position" : random.choice(positions) }) club_docs.append(club_doc) # 批量插入所有俱乐部独立文档 teams.insert_many(club_docs)
内容的提问来源于stack exchange,提问作者rhys
相关产品推荐
相关产品推荐

