sqlite3.OperationalError:没有这样的表:my\ u boardgames但它在那里

2024-10-02 12:29:49 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图通过python应用程序在sqlite中写入一个表

代码如下所示:


#skapa databasen och koppla till den
import sqlite3
conn = sqlite3.connect('Minna_spel.db')
cursor = conn.cursor()
print("Opened database successfully!!!")

#skapa tabbelerna i databasen

cursor.execute("""CREATE TABLE IF NOT EXISTS my_boardgames 
               (game_name text,
                genre text,
                recage int,
                playtime int,
                players int
                )""")

print("created tabel successfully!!!")
conn.commit()
conn.close()

def add_new_game():
    conn = sqlite3.connect('Minna_spel.db')
    cursor = conn.cursor()

    val_game_name = input("Namn?")
    val_genre = input("Genre?")
    val_rec_age = input("Rekomenderad ålder?")
    val_play_time = input("speltid?")
    val_players = input("Antal Spelare?")

    conn.execute("INSERT INTO my_boardgames (game_name,genre,recage,playtime,players)
VALUES (val_game_name,val_genre,val_rec_age,val_play_time,val_players)");
    print("spelet är nu sparat !")

    conn.commit()
    conn.close()

我不知道我做错了什么,但是当我把所有的输入输入到funktion add\u new\u games时,它就失败了:

sqlite3.OperationalError:sqlite3.OperationalError:没有这样的列:val\u game\u nameenter image description here

我查了一下数据库,确定它在那里。我做错什么了

致以最诚挚的问候


Tags: namegameinputconnectvalconnsqlite3cursor
1条回答
网友
1楼 · 发布于 2024-10-02 12:29:49

nb:为了便于阅读,我稍微重新格式化了文本字符串

您没有在查询字符串中插入变量值。下一行

conn.execute(
    "INSERT INTO my_boardgames "
    "(game_name,genre,recage,playtime,players) "
    "VALUES "
    "(val_game_name,val_genre,val_rec_age,val_play_time,val_players)");

需要替换为

conn.execute(
    "INSERT INTO my_boardgames "
    "(game_name,genre,recage,playtime,players) "
    "VALUES "
    "(?, ?, ?, ?, ?)",
    (val_game_name, val_genre, val_rec_age, val_play_time, val_players));

附加信息


正如您在评论中提到的,您是一名编程新手,我将添加更多信息

下面的代码将只使用两列来缩短行并提高可读性


阿娜ïve aproach

最明显的(但效率低下,容易出错&;不安全)解决方案如下:

conn.execute(
    "INSERT INTO my_boardgames "
    "(game_name, genre) "
    "VALUES ('" + val_game_name + "', '" + val_genre + "')")

字符串串联使得代码很难读取,您需要处理正确的值引用,这很容易出错。它也是非常脆弱和不安全的,因为某些值可能会导致查询变得无效,或者(如果恶意构建)会使查询执行完全不同的操作(SQL-Injection Attackvideo))

使用字符串格式提高可读性

第二种方法可能会引导您进行以下操作,从而使代码更具可读性

# Using traditional "printf-style" formatting
conn.execute(
    "INSERT INTO my_boardgames "
    "(game_name, genre) "
    "VALUES ('%s', '%s')" % (val_game_name , val_genre))

# Using "new-style" formatting
conn.execute(
    "INSERT INTO my_boardgames "
    "(game_name, genre) "
    "VALUES ('{}', '{}')".format(val_game_name , val_genre))

# Using f-strings
conn.execute(
    "INSERT INTO my_boardgames "
    "(game_name, genre) "
    f"VALUES ('{val_game_name}', '{val_genre}')")

这三个版本在技术上都是相同的解决方案。在将字符串发送到数据库库(本例中为SQLite)之前,它们替换字符串中的特殊占位符。得到的SQL查询字符串与使用+连接字符串的字符串相同。代码变得可读性更强一些,但由于与第一个变体完全相同的原因,代码仍然脆弱且不安全

正确的方法

这就引出了最终的解决方案(上面我的原始答案中的那个):

# Using "new-style" formatting
conn.execute(
    "INSERT INTO my_boardgames "
    "(game_name, genre) "
    "VALUES (?, ?)", (val_game_name , val_genre))

有一些微妙但重要的区别:

  • 我们向execute()函数发送两个值:带问号的查询字符串(占位符)和应该用于这些占位符的值(以前的方法都只发送一个值:我们用值手动构造的SQL字符串)
  • 我们自己不替换问号。我们让数据库处理这个问题
  • 我们不需要担心引用(注意问号周围没有引号)

这使代码保持可读性,最重要的是易于维护

让DB库处理占位符可以让DB决定如何正确引用值,从而减轻前面提到的SQL注入攻击

相关问题 更多 >

    热门问题