Discord.py机器人修改MySQL存储前缀后需重启才生效求助
问题原因
你遇到的问题是修改前缀后,机器人不重启就无法使用新前缀,本质是每次获取前缀的逻辑要么没拿到数据库最新数据,要么全局复用的cursor状态干扰了查询结果。另外你原来的查询用了f-string拼接SQL,存在SQL注入风险,得先修正这个问题。
解决办法
办法1:修复查询逻辑,避免全局cursor复用
每次查询前缀时新建cursor,避免旧cursor的状态残留影响结果,同时改用参数化查询防止注入:
def get_server_prefix(client, message): # 每次查询都新建cursor,用with语句自动处理关闭 with db.cursor(dictionary=True) as cursor: # 参数化查询,杜绝SQL注入 cursor.execute("SELECT PREFIX from prefixes where ID = %s", (message.guild.id,)) row = cursor.fetchone() # 有记录返回对应前缀,无记录返回默认前缀(比如'!') return row["PREFIX"] if row else "!"
办法2:添加本地缓存(推荐,兼顾性能与即时生效)
用字典缓存已查询过的服务器前缀,修改前缀时同时更新缓存和数据库,既减少数据库查询次数,又能让新前缀立即生效:
- 先定义全局缓存字典:
prefix_cache = {} db = mysql.connector.connect( host='localhost', user='root', password='', database='nashudb' )
- 修改获取前缀的函数,优先读取缓存:
def get_server_prefix(client, message): guild_id = message.guild.id # 缓存存在直接返回 if guild_id in prefix_cache: return prefix_cache[guild_id] # 缓存不存在则查询数据库,并存入缓存 with db.cursor(dictionary=True) as cursor: cursor.execute("SELECT PREFIX from prefixes where ID = %s", (guild_id,)) row = cursor.fetchone() prefix = row["PREFIX"] if row else "!" prefix_cache[guild_id] = prefix return prefix
- 修改前缀命令,同步更新缓存:
@commands.hybrid_command(name="prefix", description="Change prefix Nashu uses!") async def prefix(self, ctx, *, newprefix: str): guild_id = ctx.guild.id sql = "UPDATE prefixes SET PREFIX = %s WHERE ID = %s" val = (newprefix, guild_id) with db.cursor(dictionary=True) as cursor: cursor.execute(sql, val) db.commit() # 更新缓存,确保下次直接使用新前缀 prefix_cache[guild_id] = newprefix await ctx.send("Prefix changed! :3")
额外提醒
- 严禁使用f-string拼接SQL语句,参数化查询才是安全的做法。
- 必须处理服务器无前缀记录的情况,返回默认前缀避免报错。
- 用
with语句管理cursor,能自动释放资源,避免状态残留。
内容的提问来源于stack exchange,提问作者caffeinatedbaby
相关产品推荐
相关产品推荐

