python 和 sqlite3 基本问题来自 cs50

python and sqlite3 basic problem from cs50

import csv

import sqlite3

open("shows.db", "w").close()
con = sqlite3.connect('shows.db')
db = con.cursor()


db.execute("CREATE TABLE shows (id INTEGER, title TEXT, PRIMARY KEY(id))")
db.execute("CREATE TABLE genres (show_id INTEGER, genre TEXT, FOREIGN KEY(show_id) REFERENCES shows(id))")

with open("/Users/xxx/Downloads/CS50 2019 - Lecture 7 - Favorite TV Shows (Responses) - Form Responses 1.csv", "r") as file:
    reader = csv.DictReader(file)
    for row in reader:
        title = row["title"].strip().upper()
        id = db.execute("INSERT INTO shows (title) VALUES(?)", (title,))
        for genre in row["genres"].split(", "):
             db.execute("INSERT INTO genres (show_id, genre) VALUES(?, ?)", id,genre)

con.commit()

con.close()

当我 运行 这段代码时,我认为在这一行 "db.execute("INSERT INTO genres (show_id, genre) VALUES(?, ?)", id,genre)" 问题发生了。

我的控制台显示

"db.execute("INSERT INTO genres (show_id, genre) VALUES(?, ?)", id,genre)
TypeError: function takes at most 2 arguments (3 given)" 

我不明白为什么它说 3 given 尽管我给出了两个参数(id,genre)

enter image description here

我可以看到你的问题。这是因为您正在尝试将 id 和 genre 添加到查询中,就像他们在 sqlite3 文档中所做的那样。在文档中,他们做了你想在元组中做的事情,但你在函数调用中做了。

试试这个:

sql_query = ("INSERT INTO genres (show_id, genre) VALUES(?, ?)", id, genre)
db.execute(sql_query)

或者你可以把它放在一行中:

# notice how there is 2 parenthesis
#          ↓                                                             ↓
db.execute(("INSERT INTO genres (show_id, genre) VALUES(?, ?)", id, genre))
#          ↑                                                             ↑

代码有问题

  1. 这一行 returns 光标。为了获得结果,您需要调用终端操作,例如 .fetchall().fetchmany().fetchone()
id = db.execute("INSERT INTO shows (title) VALUES(?)", (title,))
  1. 因为你没有调用终端操作员或打印出结果,你不会知道 INSERT 操作 returns None, 不是实际编号

  2. 次要:一般不建议调用与built-inPython函数同名的变量。参见 id

  3. 正如我在评论中所建议的,您需要插入一个元组:

db.execute(
    "INSERT INTO genres (show_id, genre) VALUES (?, ?)",
    (id_, genre)
)

解决方案

您将需要从 shows table select title 插入后。此外,从 selection 中检索 id,然后将其插入 genres table.

代码的简化版本,展示如何做到这一点:

import csv

import sqlite3

open("shows.db", "w").close()
con = sqlite3.connect('shows.db')
db = con.cursor()


db.execute("CREATE TABLE shows (id INTEGER, title TEXT, PRIMARY KEY(id))")
db.execute("CREATE TABLE genres (show_id INTEGER, genre TEXT, FOREIGN KEY(show_id) REFERENCES shows(id))")


shows = ["FRIENS", "Game of Trhones", "Want", "Scooby Doo"]
genres = ["Comedy", "Fantasy", "Action", "Cartoon"]


for ind, show in enumerate(shows):
    db.execute("INSERT INTO shows (title) VALUES(?)", (show,))
    id_ = con.execute(
        "SELECT id FROM shows WHERE title = :show ORDER BY id DESC LIMIT 1",
        {
            "show": show
        },
    ).fetchone()
    db.execute(
        "INSERT INTO genres (show_id, genre) VALUES (?, ?)",
        (id_[0], genres[ind], )
    )

con.commit()

con.close()

有关详细信息,请查看我在 GitHub 上的代码。

SELECT 语句可能看起来有点复杂。简而言之,它采用匹配的标题和 returns 最大的 id。由于标题可能相同,因此您总是选择最后插入的匹配项。

关于调试此类问题的一般建议

  1. 尽量使用打印
  2. 使用 dir and type 函数查看方法并能够 google 类型
  3. 在 GitHub
  4. 上搜索文档或示例