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))
# ↑ ↑
代码有问题
- 这一行 returns 光标。为了获得结果,您需要调用终端操作,例如
.fetchall()
、.fetchmany()
或 .fetchone()
id = db.execute("INSERT INTO shows (title) VALUES(?)", (title,))
因为你没有调用终端操作员或打印出结果,你不会知道 INSERT
操作 returns None
, 不是实际编号
次要:一般不建议调用与built-inPython函数同名的变量。参见 id。
正如我在评论中所建议的,您需要插入一个元组:
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。由于标题可能相同,因此您总是选择最后插入的匹配项。
关于调试此类问题的一般建议
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))
# ↑ ↑
代码有问题
- 这一行 returns 光标。为了获得结果,您需要调用终端操作,例如
.fetchall()
、.fetchmany()
或.fetchone()
id = db.execute("INSERT INTO shows (title) VALUES(?)", (title,))
因为你没有调用终端操作员或打印出结果,你不会知道
INSERT
操作 returnsNone
, 不是实际编号次要:一般不建议调用与built-inPython函数同名的变量。参见 id。
正如我在评论中所建议的,您需要插入一个元组:
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。由于标题可能相同,因此您总是选择最后插入的匹配项。
关于调试此类问题的一般建议