You need to enable JavaScript to run this app. Discord.py开发!view命令:如何将SQLite3租赁数据逐行渲染为独立Discord Embed
优惠活动
大模型
产品
解决方案
定价
更多

Discord.py开发!view命令:如何将SQLite3租赁数据逐行渲染为独立Discord Embed

核心实现思路
  • 你当前用for x in rows逐行遍历数据库查询结果的大逻辑是完全正确的,完全可以沿用你之前处理用户实时输入、用字符串格式化填充Embed的逻辑。本质上数据库返回的每一行元组,和你之前暂存的用户输入值没有任何区别,只要取出对应位置的字段值替换Embed占位符即可。
  • 你之前代码的核心问题集中在3点:
    • 没有将元组中对应字段的值填充到Embed占位符里,写死的'{}'只是普通字符串,没有实际执行格式化操作
    • SQL查询的字段顺序和Embed所需字段不匹配,你遗漏了租赁价格字段,还把“租赁名称”的字段名错写成了“Bot Name”
    • 默认SQLite返回的元组没有字段标识,靠数字索引取值很容易因查询顺序变动出现填充错位
修正步骤与参考实现

第一步:调整SQLite配置降低出错概率

在你初始化数据库连接的位置加一行配置,让所有查询返回的行支持通过字段名取值,不需要靠数字下标数顺序:

# 初始化数据库连接后配置
conn = sqlite3.connect('rentals.db')
conn.row_factory = sqlite3.Row  # 将查询返回行转为类字典结构
cursor = conn.cursor()

配置完成后,后续查询的每一行都可以通过x['name']、x['renter']这类字段名直接取值,从根源避免索引错位问题。

第二步:修正!view命令的字段填充逻辑

将你之前循环内的占位符替换为实际字段取值,使用你熟悉的字符串格式化逻辑即可,参考代码如下:

# 文件顶部提前导入需要的依赖
import asyncio
import discord

if message.content.startswith('!view'):
    rows = cursor.execute("SELECT name, renter, duration, price, start, end FROM rental").fetchall()
    # 没有查询到记录时直接提示,避免发送空内容的Embed
    if not rows:
        await message.channel.send("目前还没有存储任何租赁记录")
        return
    for rental in rows:
        embed = discord.Embed(title="租赁详情", color=0x0000FF)
        embed.set_thumbnail(url="https://icon-library.com/images/database-png-icon/database-png-icon-22.jpg")
        # 直接通过字段名取值填充,和你处理用户输入的逻辑完全一致
        embed.add_field(name='租赁名称', value=rental['name'], inline=False)
        embed.add_field(name='承租方名称', value=rental['renter'], inline=False)
        embed.add_field(name='租赁时长', value=f"{rental['duration']} 天", inline=False)
        embed.add_field(name='租赁价格', value=rental['price'], inline=False)
        embed.add_field(name='开始日期', value=rental['start'], inline=False)
        embed.add_field(name='结束日期', value=rental['end'], inline=False)
        embed.set_footer(icon_url='https://pbs.twimg.com/profile_images/1325672283881484289/oaGtVIOD_400x400.png', text='Created by @Expected')
        await message.channel.send(embed=embed)
        # 记录较多时加0.5秒延时,避免短时间发消息触发Discord速率限制
        await asyncio.sleep(0.5)
注意事项
  • 如果你不想调整SQLite的行工厂配置,也可以直接用原来的元组索引取值:按照你当前的SQL查询顺序name, renter, duration, price, start, end,元组的0到5位依次对应上述字段,直接用rental[0]到rental[5]取值即可,但这种方式在后续修改查询字段顺序时很容易出现填充错位,不推荐长期使用。
  • 你之前写的value='{}'没有生效,本质是没有对字符串执行格式化操作,不管是用'{}'.format(取值)、f-string这类常见格式化方式,在数据库取值场景下和用户输入场景下是完全通用的,不存在适配差异。
  • 如果后续租赁记录数量较多,逐行发独立Embed的体验可以进一步优化,但当前你要求单条记录对应单条独立Embed的需求,上述代码可以直接满足。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.01 14:36:07