class 中赋值前引用的局部变量?与 python,不和谐

Local variable referenced before assignment in class? with python, discordpy

我在使用 python 中的 discordpy 重写分支制作齿轮时遇到了一些麻烦。

我正在尝试使用 mysql 连接器创建一个命令来启动与数据库的连接并创建一个简单的 table。问题是,当我像官方 mysql 文档中所述定义游标变量时,出现错误: "local variable 'cnx' referenced before assignment"

现在是代码:

import discord
from discord.ext import commands
import json
import asyncio
import mysql.connector
from mysql.connector import errorcode

with open("config.json") as configfile:
    config = json.load(configfile)

class testcog:

    def __init__(self, client):
        self.client = client


    @commands.command()
    async def dbconnect(self, ctx):
        await ctx.message.author.send('I\'m connecting to the database, please be patient.')

        try:
            cnx = mysql.connector.connect(user=config['sqlconfig']['user'], password=config['sqlconfig']['password'],
                                          host=config['sqlconfig']['host'],
                                          database=config['sqlconfig']['database'])
        except mysql.connector.Error as err:
            if err.errno == errorcode.ER_ACCESS_DENIED_ERROR:
                print("Something is wrong with your user name or password")
            elif err.errno == errorcode.ER_BAD_DB_ERROR:
                print("Database does not exist")
            else:
                print(err)
        else:
            cnx.close()

        cursor = cnx.cursor()

        TABLES = {}
        TABLES['employee'] = (
            "CREATE TABLE `employee` ("
            "  `emp_no` int(11) NOT NULL AUTO_INCREMENT,"
            "  `birth_date` date NOT NULL,"
            "  `first_name` varchar(14) NOT NULL,"
            "  `last_name` varchar(16) NOT NULL,"
            "  `gender` enum('M','F') NOT NULL,"
            "  `hire_date` date NOT NULL,"
            "  PRIMARY KEY  (`emp_no`)"
            ") ENGINE=InnoDB")

        for table_name in TABLES:
            table_description = TABLES[table_name]
            try:
                print("Creating table {}: ".format(table_name), end='')
                cursor.execute(table_description)
            except mysql.connector.Error as err:
                if err.errno == errorcode.ER_TABLE_EXISTS_ERROR:
                    print("already exists.")
                else:
                    print(err.msg)
            else:
                print("OK")

        cursor.close()
        cnx.close()


def setup(client):
    client.add_cog(testcog(client))

table 和创建它的代码是直接从官方文档中复制的。 给我错误的代码是: cursor = cnx.cursor() 就在创建 TABLES 字典之前。

我不明白我做错了什么,非常感谢帮助。

我想我可以为你提供一些帮助!

在 cog 文件中工作时,您需要在主 class 中继承 commands.Cog。除此之外,您应该异步打开和关闭 json 文件。

我们将异步与 discord.py 结合使用,这样如果多人使用您的命令,机器人就不会备份(这样机器人就可以一次做多件事)。有一个用于 MySql 的异步库和用于打开 json 文件的异步库,所以让我们研究一下如何使用它们。

您可以在此处查看 aiomysql 文档:https://aiomysql.readthedocs.io/en/latest/

让我们着手解决您的问题。为了做到这一点,我们需要确保我们的机器人是为我们的数据库设置的。我们设置了一个叫做“池”的东西,它随着数据库的变化而变化。

我将向您展示本例中的文件结构:

main.py
/cogs
   testcog.py
# When creating our bot, we want to setup our db (database) connection, so we can reference it later

from discord.ext import commands
import discord
import aiomysql
import asyncio
import aiofiles, json

loop = asyncio.get_event_loop()

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

@bot.event
async def on_ready():
    config = json.loads(await(await aiofiles.open("/home/pi/Desktop/Experimental/prestagingapi.json")).read())
    bot.pool = await aiomysql.create_pool(host=config['sqlconfig']['host'], port = 0000, user = config['sqlconfig']['user'], 
                                        password = config['sqlconfig']['password'], 
                                        db = config['sqlconfig']['database'], loop=loop)
    print("Bot is online!")


# We need to load our cogs and setup our db loop to reference it later
initial_extension = (
    "cogs.testcog",
)

for extension in initial_extension:
    bot.load_extension(extension)

bot.run("YOUR_TOKEN", reconnect=True)

现在,我们可以在齿轮内部工作以设置所有内容。我将这个 cog 的文件命名为文件夹内的 testcog.py cogs.

import discord
from discord.ext import commands


class testCog(commands.Cog): # I defined that our class inherits the cog for discords
    def __init__(self, bot):
        self.bot = bot

    @commands.command()
    async def create_table(self, ctx):
        await ctx.author.send('I\'m connecting to the database, please be patient.') #ctx.message.author is ctx.author

        # now you can create your db connection here:
        # looking at the aiomysql documentation, we can create a connection and execute what we need
        async with self.bot.pool.acquire() as conn:
            async with conn.cursor() as cur:
                # in order to execute something (creaing a table for ex), we can do this:
                await cur.execute()

def setup(bot): # every cog needs a setup function
    bot.add_cog(testCog(bot))