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

Discord.py命令重复提交数据库问题及代码刷新方案咨询

修复Discord.py crear_dni命令重复提交问题的方案

1. 修复命令内的检查逻辑

核心问题之一是未正确查询数据库就使用row变量,导致无法识别用户是否已执行过命令。正确流程是:每次用户调用命令时,先查询数据库中是否存在该用户的记录,再决定是否执行后续操作。

示例代码(以SQLite为例,其他数据库逻辑通用):

import discord
from discord.ext import commands
import sqlite3

bot = commands.Bot(command_prefix='!', intents=discord.Intents.all())

# 获取数据库连接(确保每次操作正确关闭连接)
def get_db_connection():
    conn = sqlite3.connect('dni_database.db')
    conn.row_factory = sqlite3.Row
    return conn

@bot.command(name='crear_dni')
async def crear_dni(ctx):
    user_id = ctx.author.id
    conn = get_db_connection()
    cursor = conn.cursor()

    # 先查询用户是否已有记录
    cursor.execute('SELECT * FROM dni_records WHERE user_id = ?', (user_id,))
    row = cursor.fetchone()

    if row is not None:
        await ctx.send("你已经创建过DNI了,不能重复执行此命令!")
        conn.close()
        return

    # 无记录则执行创建逻辑
    try:
        cursor.execute('INSERT INTO dni_records (user_id, created_at) VALUES (?, CURRENT_TIMESTAMP)', (user_id,))
        conn.commit()
        await ctx.send("DNI创建成功!")
    except sqlite3.Error as e:
        await ctx.send(f"创建失败:{str(e)}")
    finally:
        conn.close()

2. 数据库层面添加唯一约束(从根源阻止重复)

即使命令逻辑出现疏漏,也可以通过数据库的唯一约束强制拦截重复插入。针对user_id字段添加唯一索引:

-- SQLite语法
CREATE UNIQUE INDEX idx_unique_user_id ON dni_records(user_id);

-- MySQL语法
ALTER TABLE dni_records ADD UNIQUE KEY idx_unique_user_id(user_id);

添加后,重复提交会触发唯一性冲突错误,可在代码中捕获并提示用户:

try:
    cursor.execute('INSERT INTO dni_records (user_id, created_at) VALUES (?, CURRENT_TIMESTAMP)', (user_id,))
    conn.commit()
    await ctx.send("DNI创建成功!")
except sqlite3.IntegrityError:
    await ctx.send("你已经创建过DNI了,不能重复执行此命令!")
except sqlite3.Error as e:
    await ctx.send(f"创建失败:{str(e)}")
finally:
    conn.close()

3. 可选:用插入语法直接避免重复

如果不想依赖错误捕获,可使用INSERT OR IGNORE(SQLite)或INSERT IGNORE(MySQL)语法,直接跳过重复插入:

# SQLite示例
cursor.execute('INSERT OR IGNORE INTO dni_records (user_id, created_at) VALUES (?, CURRENT_TIMESTAMP)', (user_id,))
if cursor.rowcount == 0:
    await ctx.send("你已经创建过DNI了,不能重复执行此命令!")
else:
    conn.commit()
    await ctx.send("DNI创建成功!")

关于“刷新数据库”的说明

不需要额外的“刷新”操作,只要确保每次命令调用时都执行实时查询,并正确处理数据库连接的打开/关闭(或使用连接池),就能获取最新的用户记录。如果之前存在缓存row变量的情况,直接移除缓存,每次查询即可。

内容的提问来源于stack exchange,提问作者Dark Fire

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 12:25:13