Discord.py Cog调用SQLite3 fetch函数遇OperationalError语法错误求助
问题解决:SQLite语法错误与SQL注入风险修复
错误根源
你的代码直接用f-string拼接SQL语句,当传入的id包含特殊字符(比如Discord用户提及格式<@用户ID>)时,会破坏SQL语法结构,触发near "<": syntax error错误。同时这种写法存在严重的SQL注入风险,可能导致数据库被恶意篡改。
修复方案
1. 修正数据库操作类(db.py)
改用SQLite的参数化查询(占位符?)替代字符串拼接,同时优化返回值处理:
import sqlite3 class database: def __init__(self) -> None: self.conn = sqlite3.connect("db.db") self.c = self.conn.cursor() def update(self, name, value, user_id) -> bool: # 参数化查询,避免SQL注入和语法错误 self.c.execute("UPDATE users SET ?=? WHERE id=?", (name, value, user_id)) self.conn.commit() return self.c.rowcount >= 1 def fetch(self, name, user_id): # 参数化查询,安全传递参数 self.c.execute("SELECT ? FROM users WHERE id=?", (name, user_id)) res = self.c.fetchone() if res: # 返回字段的单个值,而非元组 return res[0] else: return "No user found"
2. 修正Cog调用代码(russian_roulette.py)
现在fetch直接返回数值,无需再用sum()处理:
tokens = db.fetch("tokens", ctx.author.id) # 确保传入纯数字用户ID,而非提及格式字符串 if tokens == 'No user found': await ctx.reply('Create an account first by running `.start`') else: # tokens已经是整数,可直接使用 # 示例:print(tokens)
额外说明
- 确保传入的
user_id是Discord用户的纯数字ID(比如通过ctx.author.id获取),不要传入带<@>的提及格式字符串,避免格式问题。 - 参数化查询是数据库操作的标准安全规范,既能彻底规避SQL注入风险,又能解决特殊字符导致的语法错误。
内容的提问来源于stack exchange,提问作者Jivesh Bisht
相关产品推荐
相关产品推荐

