如何在app_commands.Choice中从数据库获取数据?

问题描述 投票:0回答:1

获取名单并放入app_commands.Choice

我想确保当我输入 /a 时,它会显示将从 music.db 数据库接收的列表。现在的他是这样的

click

我需要折叠将从 music.db 数据库接收的标题列表。一个看起来像什么的例子

click

而且当姓名列表较多时,需要进行搜索,如示例所示,以免在大列表中搜索不到所需的姓名。

如果您需要更多详细信息,请写信。我使用 pycord“语音”库以及 disnake

数据库创建

conn = sqlite3.connect('music.db')
cursor = conn.cursor()

cursor.execute('''CREATE TABLE IF NOT EXISTS music
                (name TEXT PRIMARY KEY, path TEXT)''')
conn.commit()

conn.close()

命令代码

@commands.slash_command(name="a", description="Добавить звук")
    async def a(self, ctx, название = discord.Option(str)):
        conn = sqlite3.connect('music.db')
        cursor = conn.cursor()
        cursor.execute("SELECT path FROM music WHERE name = ?", (название,))
        result = cursor.fetchone()
        if result:
            path = result[0]
            if ctx.author.voice:
                channel = ctx.author.voice.channel
                voice_client = await channel.connect()
                voice_client.play(discord.FFmpegPCMAudio(path), after=lambda e: print(f'Звук воспроизведен {название}'))
                emb = discord.Embed(title = 'Звук', colour = discord.Color.green() )
                await ctx.channel.purge(limit=1)
                emb.set_footer(text = f'Вы запустили звук')
                await ctx.respond(embed=emb)  
                await ctx.delete(delay=10)

                while voice_client.is_playing():
                    await asyncio.sleep(1)

                await voice_client.disconnect()
            else:
                emb = discord.Embed(title = 'Звук', colour = discord.Color.red() )
                await ctx.channel.purge(limit=1)
                emb.set_footer(text = f'Вы не подключены к голосовому каналу. ')
                await ctx.respond(embed=emb)  
                await ctx.delete(delay=10)
        else:
            emb = discord.Embed(title = 'Звук', colour = discord.Color.red() )
            await ctx.channel.purge(limit=1)
            emb.set_footer(text = f'Аудиофайл с таким названием не найден.')
            await ctx.respond(embed=emb)  
            await ctx.delete(delay=10)

        conn.close()
discord discord.py bots pycord disnake
1个回答
0
投票

第一步:创建数据库(您可能已经有了这个)

因为您使用的是 sqllite3,这使得这变得非常简单。 下面,我创建了一个简单的数据库结构,我将用它来搜索基本路径,就像您已经提供的音乐路径一样:

music = [('beans', 'bean_path'), ('potatoes', 'potato_path'), ('test', 'testpath'), ('test1', 'testpath1'), ('testing', 'testpath2')]

for name_ in music:
    cursor.execute("""
    INSERT INTO music VALUES (?, ?)""", (name_[0], name_[1]))
    conn.commit()

此代码创建以下数据库,我们稍后将在 Py-cord 的自动选择功能中使用它: Database image

第二步:参数

在 Py-cord 中,斜杠命令中的选项参数可以自动完成(来源如下)。文档是这样说的:

选项的自动完成处理程序。接受采用 AutocompleteContext 的单个参数的可调用(同步或异步)。可调用对象必须返回 str 或 OptionChoice 的可迭代对象。或者,可以使用discord.utils.basic_autocomplete() 代替可调用函数。

对于此示例,我为此自动完成选项使用了异步处理程序:

def autocomplete(auto_text):
    # Note: You closed the con earlier, but you didn't have to do that
    cur_execution = cursor.execute("SELECT path FROM music WHERE name like ? || '%'", (auto_text.value,))  # Get the music from the db
    # See more about the like operator here: https://stackoverflow.com/questions/55207123/how-to-match-number-start-with-through-query-sqlite
    options = []
    for name in cur_execution.fetchall():  # get all values
        options.append(discord.OptionChoice(name=name[0]))
    if not options:  # if options is empty
        cur_execution = cursor.execute("SELECT * FROM music")  # Fetch all music because we have no options
        for name in cur_execution.fetchall():
            options.append(discord.OptionChoice(name=name[0]))
    return options

创建函数后,我们可以将其与斜杠命令中的参数联系起来:

@bot.slash_command()
async def get_from_database(ctx, name: discord.Option(str, autocomplete=autocomplete)):  # name autocompetes to the autocomplete function
    await ctx.respond(name)

最终结果

以下是当您没有输入任何内容时的样子:

End product

以下是当您输入部分内容时会发生的情况:

When you search

来源:

© www.soinside.com 2019 - 2024. All rights reserved.