discord.py警告系统MongoDB数据更新异常:无法追加警告对象而是替换原对象
解决Discord.py警告系统MongoDB追加数据问题
我来帮你搞定这个警告系统的问题!你的核心问题是没有正确判断用户是否已有警告记录,而且在更新时误用了操作符和变量,导致每次都覆盖而不是追加。咱们一步步修改:
原代码的核心问题
first_warning变量初始化后始终为True,没有根据数据库查询结果动态更新,导致每次都执行upsert覆盖原有数据- 查询用户记录后没有校验是否存在,直接默认是首次警告
- 更新操作中键名不匹配(原数据用
warn数组,你写成了warns),查询条件错误地把user.id当成字符串而非变量 - 使用
$push时逻辑错误,不需要先取数组再append,MongoDB的$push可以直接追加单个对象
修改后的完整代码
@commands.command() @commands.guild_only() # @commands.has_guild_permissions(kick_members=True) async def warn(self, ctx, user: discord.User, *, reason=None): if user is None: await ctx.send("You have not provided a user!") return if user.bot: await ctx.send(f"<@{ctx.author.id}>, you cannot warn a bot!") return if user.id == ctx.author.id: embed = discord.Embed(description=f"<@{ctx.author.id}>, you are not allowed to warn yourself!") embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar_url) embed.set_footer(text=f"{ctx.message.guild.name} Custom Designed Bot") embed.timestamp = ctx.message.created_at await ctx.send(embed=embed) return # 处理默认原因 reason = reason or "No reason provided" # 查询用户是否已有警告记录 existing_warns = await self.bot.warns.find_by_id({"_id": user.id}) # 构造新的警告对象 new_warn_entry = { "PunishType": 'warn', "Moderator": ctx.author.id, "Reason": reason, "Timestamp": ctx.message.created_at # 建议加上时间戳,方便后续查看 } if not existing_warns: # 首次警告,插入新文档 warn_doc = { "_id": user.id, "guild": ctx.guild.id, "warn": [new_warn_entry] } await self.bot.warns.upsert(warn_doc) embed_desc = f"<@{ctx.author.id}> has warned <@{user.id}> for: {reason}" else: # 已有警告,追加新的警告到数组 await self.bot.warns.update( {"_id": user.id}, {"$push": {"warn": new_warn_entry}} # 使用$push直接追加单个对象 ) embed_desc = f"<@{ctx.author.id}> has added another warning to <@{user.id}> for: {reason}" # 发送成功提示Embed embed = discord.Embed(description=embed_desc) embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar_url) embed.timestamp = ctx.message.created_at await ctx.send(embed=embed)
关键修改点说明
- 动态判断首次警告:通过
existing_warns = await self.bot.warns.find_by_id({"_id": user.id})查询数据库,根据返回结果判断是否为首次警告 - 修正
$push用法:直接使用{"$push": {"warn": new_warn_entry}}让MongoDB自动把新警告对象追加到warn数组末尾,不需要手动操作数组 - 修复变量和键名错误:把查询条件里的
"user.id"改成user.id(去掉引号,使用变量值),统一数组键名为warn - 新增时间戳:给每个警告对象加上
Timestamp字段,方便后续查看警告时间 - 优化提示内容:根据是否首次警告,发送不同的提示信息
这样修改后,每次执行警告命令时,系统会自动判断用户是否已有警告记录,首次则插入新文档,非首次则追加新的警告对象到数组中,不会再覆盖原有数据啦!
内容的提问来源于stack exchange,提问作者Jango DarkWind
相关产品推荐
相关产品推荐

