【问题标题】:Why is my Sqlite database being deleted after each restart of my code? (Python)为什么每次重新启动代码后都会删除我的 Sqlite 数据库? (Python)
【发布时间】:2021-09-22 11:29:04
【问题描述】:

我正在制作一个不和谐的机器人,我希望它具有自定义前缀功能。它有点工作,但每次我重新启动它 - 数据库都消失了。

我尝试将 try - except 语句替换为 """CREATE TABLE IF NOT EXISTS"""。但它似乎也不能正常工作。 我认为我在数据库初始化中做错了。

这是我与此功能相关的代码:

import sqlite3
import discord
from discord.ext import commands
from discord.utils import get
connection = sqlite3.connect('Server_Settings.db')
cursor = connection.cursor()
try:
        cursor.execute( """CREATE TABLE Settings (_id INTEGER, MD STRING, AR STRING, TC INTEGER, 
        AC INTEGER, WC INTEGER, IACS INTEGER, ITCS INTEGER, IWCS INTEGER,Prefix STRING )""")
except:
        print("no need")

def get_prefix(client, message):
    global Prefix
    TechChannel1 = int
    IsTChannelSet1 = int
    AnnouncementChannel1 = int
    IsAChannelSet1 = int
    WelcomeChannel1 = int
    IsWChannelSet1 = int
    _id = message.guild.id
    check = cursor.execute("SELECT _id FROM Settings WHERE _id = _id")
    result = cursor.fetchone()
    if result != None:
        check = cursor.execute("SELECT Prefix FROM Settings WHERE _id = _id")
        result = cursor.fetchone()
        if result[0] != None:
            Prefix = result[0]
            print(Prefix)
        else:
            cursor.execute("UPDATE Settings SET Prefix = '!' WHERE _id = ?", (_id))
    else:
        if IsTChannelSet == False:
            TechChannel1 = 0
            IsTChannelSet1 = 0
        else:
            IsTChannelSet1 = 1
        if IsAChannelSet == False:
            AnnouncementChannel1 = 0
            IsAChannelSet1 = 0
        else:
            IsAChannelSet1 = 1
        if IsWChannelSet == False:
            WelcomeChannel1 = 0
            IsWChannelSet1 = 0
        else:
            IsWChannelSet1 = 1
            cursor.execute("INSERT INTO Settings (_id,MD,AR,TC,AC,WC,IACS,ITCS,IWCS,Prefix) VALUES (?,?,?,?,?,?,?,?,?,?)",(_id, ModRole, AnnouncementRole, TechChannel1, AnnouncementChannel1, WelcomeChannel1, IsAChannelSet1,
             IsTChannelSet1, IsWChannelSet1, '!'))
    return Prefix

# prefix
bot = commands.Bot(command_prefix=get_prefix)
client = discord.Client
bot.remove_command("help")


@bot.command(name="set.prefix")
@commands.has_role(ModRole)
async def set_prefix(ctx, prefix):
    global Prefix
    mention = ctx.author.mention
    _id = ctx.guild.id
    if len(prefix) > 1:
        embed = discord.Embed(
            title="Attention",
            description="It is not recommended to use prefix with length more than 1 character",
            color= discord.Color.dark_magenta()
        )
        await ctx.channel.send(embed=embed)
    else:
        pass
    cursor.execute("UPDATE Settings SET Prefix = ? WHERE _id = ?", (prefix, _id))
    embed = discord.Embed(title=f"Updating prefix...", description=f"It might take a while", colour=discord.Color.green())
    mes = await ctx.channel.send(embed=embed)
    newmes = await ctx.fetch_message(mes.id)
    cursor.execute("SELECT Prefix FROM Settings WHERE _id = _id")
    result = cursor.fetchone()
    print(result[0], prefix)
    if result[0] == prefix:
        embed = discord.Embed(title=f"@everyone", description=f"My new prefix is {prefix}", colour=discord.Color.green())
        await newmes.edit(embed=embed)
    else:
        embed = discord.Embed(title=f"Oops! Something went wrong", description=f"Try again later", colour=discord.Color.red())
        await newmes.edit(embed=embed)

运行代码:

重启代码后:

提前致谢!

【问题讨论】:

    标签: python sqlite discord discord.py


    【解决方案1】:

    好的,所以问题在于缺少 commit() 语句。注意到这一点的人是这样说的:“我没有看到任何 commit() 语句。您通常必须调用 (...cursor or connection?) 的 commit() 方法来编写更改或一组更改数据库 - 否则您的程序可能在内存中运行良好,但不会保存任何内容。” 我不确定我是否完全正确,但这是我的代码现在的样子:

    def get_prefix(client, message):
           global Prefix
            TechChannel1 = int
            IsTChannelSet1 = int
            AnnouncementChannel1 = int
            IsAChannelSet1 = int
            WelcomeChannel1 = int
            IsWChannelSet1 = int
            _id = message.guild.id
            check = cursor.execute("SELECT _id FROM Settings WHERE _id = _id")
            result = cursor.fetchone()
            if result != None:
                check = cursor.execute("SELECT Prefix FROM Settings WHERE _id = _id")
                result = cursor.fetchone()
                if result[0] != None:
                    Prefix = result[0]
                    connection.commit() # Commit statement added
                else:
                    cursor.execute("UPDATE Settings SET Prefix = '!' WHERE _id = ?", (_id))
                    connection.commit() # Commit statement added
            else:
                if IsTChannelSet == False:
                    TechChannel1 = 0
                    IsTChannelSet1 = 0
                else:
                    IsTChannelSet1 = 1
                if IsAChannelSet == False:
                    AnnouncementChannel1 = 0
                    IsAChannelSet1 = 0
                else:
                    IsAChannelSet1 = 1
                if IsWChannelSet == False:
                    WelcomeChannel1 = 0
                    IsWChannelSet1 = 0
                else:
                    IsWChannelSet1 = 1
                cursor.execute("INSERT INTO Settings (_id,MD,AR,TC,AC,WC,IACS,ITCS,IWCS,Prefix) VALUES (?,?,?,?,?,?,?,?,?,?)",(_id, ModRole, AnnouncementRole, TechChannel1, AnnouncementChannel1, WelcomeChannel1, IsAChannelSet1,
                     IsTChannelSet1, IsWChannelSet1, '!'))
    
            return Prefix
        
        #Set commands
        @bot.command(name="set.prefix")
        @commands.has_role(ModRole)
        async def set_prefix(ctx, prefix):
            global Prefix
            mention = ctx.author.mention
            _id = ctx.guild.id
            if len(prefix) > 1:
                embed = discord.Embed(
                    title="Attention",
                    description="It is not recommended to use prefix with length more than 1 character",
                    color= discord.Color.dark_magenta()
                )
                await ctx.channel.send(embed=embed)
            else:
                pass
            cursor.execute("UPDATE Settings SET Prefix = ? WHERE _id = ?", (prefix, _id))
            embed = discord.Embed(title=f"Updating prefix...", description=f"It might take a while", colour=discord.Color.green())
            mes = await ctx.channel.send(embed=embed)
            newmes = await ctx.fetch_message(mes.id)
            cursor.execute("SELECT Prefix FROM Settings WHERE _id = _id")
            result = cursor.fetchone()
            connection.commit() #Commit statement added
            print(result[0], prefix)
            if result[0] == prefix:
                embed = discord.Embed(title=f"@everyone", description=f"My new prefix is {prefix}", colour=discord.Color.green())
                await newmes.edit(embed=embed)
            else:
                embed = discord.Embed(title=f"Oops! Something went wrong", description=f"Try again later", colour=discord.Color.red())
                await newmes.edit(embed=embed)  
    

    【讨论】:

      【解决方案2】:

      问题

      您的某些查询似乎是硬编码的,并且没有使用 _id 参数,因此无法识别以前存储的值,例如:

       check = cursor.execute("SELECT _id FROM Settings WHERE _id = _id")
      

      check = cursor.execute("SELECT Prefix FROM Settings WHERE _id = _id")
      

      建议解决方案

      尝试将这些更改为您的参数化查询,例如:

      cursor.execute("SELECT _id FROM Settings WHERE _id = ?", (_id))
      

      check = cursor.execute("SELECT Prefix FROM Settings WHERE _id =  ?", (_id))
      

      到目前为止,我在您的共享代码中看到了 3 个这样的案例。

      更新 1

      引用discord api heremessage.guild.id 应该是snowflake type,它们在api 中作为字符串返回。

      def get_prefix(client, message):
              global Prefix
              # Previously these were being initialized to a type and not a value
              # Python is an interpreted language that infers type based on first
              # value assignment. I've assigned a default value of `0`. You may 
              # use a value of choice or `None`
              TechChannel1 = 0
              IsTChannelSet1 = 0
              AnnouncementChannel1 = 0
              IsAChannelSet1 = 0
              WelcomeChannel1 = 0
              IsWChannelSet1 = 0
      
              _id = message.guild.id
              # This should prevent the most recent error `ValueError: parameters are of unsupported type`
              # Adding a check here as it seems from your response shared that
              # The id value from the `message.guild` may be None. You should
              # confirm with the API/docs of discord api to determine whether 
              # this is expected behaviour
              if _id is not None:
                  # instead of running a similar query twice to get details
                  # from the same row, you can pull all you need in one query
                  # You do no seem to use the `id` returned since you are already querying with it
                  check = cursor.execute("SELECT Prefix FROM Settings WHERE _id = ?", (_id))
                  result = cursor.fetchone()
      
              if result != None:
                  # No longer needed because of edit above
                  # check = cursor.execute("SELECT Prefix FROM Settings WHERE _id = ?", (_id))
                  # result = cursor.fetchone()
                  if result[0] != None:
                      Prefix = result[0]
                      
                  else:
                      cursor.execute("UPDATE Settings SET Prefix = '!' WHERE _id = ?", (_id))
                      connection.commit() # Commit statement added
              else:
                  if IsTChannelSet == False:
                      TechChannel1 = 0
                      IsTChannelSet1 = 0
                  else:
                      IsTChannelSet1 = 1
                  if IsAChannelSet == False:
                      AnnouncementChannel1 = 0
                      IsAChannelSet1 = 0
                  else:
                      IsAChannelSet1 = 1
                  if IsWChannelSet == False:
                      WelcomeChannel1 = 0
                      IsWChannelSet1 = 0
                  else:
                      IsWChannelSet1 = 1
                  cursor.execute("INSERT INTO Settings (_id,MD,AR,TC,AC,WC,IACS,ITCS,IWCS,Prefix) VALUES (?,?,?,?,?,?,?,?,?,?)",(_id, ModRole, AnnouncementRole, TechChannel1, AnnouncementChannel1, WelcomeChannel1, IsAChannelSet1,
                       IsTChannelSet1, IsWChannelSet1, '!'))
                  connection.commit() # Commit statement added
              return Prefix
      

      如果这有帮助,请告诉我。

      【讨论】:

      • 我试过了,但是会报错:check = cursor.execute("SELECT _id FROM Settings WHERE _id = ?", (_id)) ValueError: parameters are unsupported type
      • 哪一行出现错误?当你 print(_id)print(type(_id)) 时,你看到了什么值?
      • 在第 68 行(我第一次使用以下语句:check = cursor.execute("SELECT _id FROM Settings WHERE _id = ?", (_id)))。 Print(_id) - 无。 Print(type(_id) -
      • 我已经更新了我的答案。除了添加 commit() 语句之外,请让我知道这是否有效。
      • 是的,它有效。但我不明白guild.id 怎么可能没有。也许我做错了什么......(不知何故)。无论如何感谢您的帮助。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-14
      • 2012-07-24
      相关资源
      最近更新 更多