Ссылка на локальную переменную перед назначением в классе? с питоном, дискордпи

у меня возникли проблемы с созданием винтика с веткой перезаписи discordpy в python.

Я пытаюсь создать команду для запуска подключения к базе данных с помощью соединителя mysql и создания простой таблицы. Проблема в том, что когда я определяю переменную курсора, как указано в официальных документах mysql, я получаю сообщение об ошибке: «Локальная переменная« cnx », на которую ссылается перед назначением»

Теперь это код:

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))

Таблица и код для ее создания были скопированы непосредственно из официальной документации. Фрагмент кода, который дает мне ошибку: cursor = cnx.cursor() непосредственно перед созданием словаря TABLES.

Я не понимаю, что я делаю неправильно, помощь очень ценится.


person Emmanuele D'Ettorre    schedule 01.03.2019    source источник
comment
Если вам не удается подключиться, вы все равно пытаетесь выполнить cnx.cursor(), даже несмотря на то, что cnx не определено. Вы должны добавить return в блок except. Кроме того, этот блок else выглядит неправильно, я не уверен, что он должен делать, но похоже, что он закрывает соединение, как только оно открывается.   -  person Patrick Haugh    schedule 02.03.2019
comment
я использую оператор try, чтобы получить все ошибки соединения, и их нет, поэтому я думаю, что мое соединение с базой данных хорошее. Даже если я удалю последний оператор else блока try, это даст мне ошибку cursor = cnx.cursor(). Я использую cnx в блоке try, так как же возможно, что ошибка говорит, что я использую cnx перед его определением?   -  person Emmanuele D'Ettorre    schedule 02.03.2019


Ответы (1)


Я думаю, что могу оказать вам некоторую помощь!

При работе с файлом cog вам необходимо наследовать 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)

Теперь мы можем работать внутри нашего винтика, чтобы все настроить. Я назвал файл этого винтика 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))
person Iced Chai    schedule 20.12.2020