You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 11:45:04