我作为一个有趣的副项目一直在使用的代码一直工作得非常好,直到运行搜索功能时我才更新了我以前从未遇到过的错误。我试图弄清楚它为什么起作用,因为过去它已经突然之间没有了。
import sqlite3
def connect():
"""Set up a connection with the database."""
conn_obj = sqlite3.connect("movies.db")
cur_obj = conn_obj.cursor()
cur_obj.execute("CREATE TABLE IF NOT EXISTS "
"movie (id integer PRIMARY KEY, "
"title text, "
"director text, "
"year integer, "
"studio integer)")
conn_obj.commit()
conn_obj.close()
def insert(title, director, year, studio):
"""Insert entry into database."""
conn_obj = sqlite3.connect("movies.db")
cur_obj = conn_obj.cursor()
cur_obj.execute("INSERT INTO movie "
"VALUES (NULL, ?, ?, ?, ?)", (title, director, year, studio))
conn_obj.commit()
conn_obj.close()
def view():
"""View all database entries."""
conn_obj = sqlite3.connect("movies.db")
cur_obj = conn_obj.cursor()
cur_obj.execute("SELECT * FROM movie")
rows = cur_obj.fetchall()
conn_obj.close()
return rows
def update(id, title, author, year, isbn):
"""Update a database entry."""
conn_obj = sqlite3.connect("movies.db")
cur_obj = conn_obj.cursor()
cur_obj.execute("UPDATE movie "
"SET title = ?, "
"director = ?, "
"year = ?, "
"studio = ? "
"WHERE id = ?",
(title, director, year, studio, id))
conn_obj.commit()
conn_obj.close()
def delete(id):
"""Delete a database entry."""
conn_obj = sqlite3.connect("movies.db")
cur_obj = conn_obj.cursor()
cur_obj.execute("DELETE FROM movie "
"WHERE id = ?", (id,))
conn_obj.commit()
conn_obj.close()
def search(title = "", director = "", year = "", studio = ""):
"""Search for a database entry."""
conn_obj = sqlite3.connect("movies.db")
cur_obj = conn_obj.cursor()
cur_obj.execute("SELECT * "
"FROM movie "
"WHERE title = ? OR director = ? OR year = ? OR studio = ?",
(title, director, year, studio))
rows = cur_obj.fetchall()
conn_obj.close()
return rows
connect()
这是代码的后端,主要处理代码的主干,而前端处理tkinter GUI。问题在于代码后端的第68行,由于附近的错误,它是搜索功能的一部分。解释问题在于这行代码(标题,导演,年份,工作室,运行时,rtscore,id))因为 sqlite3.OperationalError:near"?":语法错误
from tkinter import *
import backend
import urllib.request
import urllib.parse
import re
import webbrowser
def add_command():
"""Insert entry via button."""
backend.insert(title_text.get(),
director_text.get(),
year_text.get(),
studio_text.get(),
runtime_text.get(),
rtscore_text.get())
listing.delete(0, END)
listing.insert(END,
(title_text.get(),
director_text.get(),
year_text.get(),
studio_text.get(),
runtime_text.get(),
rtscore_text.get()))
def view_command():
"""View entries via button."""
listing.delete(0, END)
for row in backend.view():
listing.insert(END, row)
def update_command():
"""Update entry via button."""
backend.update(selected_tuple[0],
title_text.get(),
director_text.get(),
year_text.get(),
studio_text.get(),
runtime_text.get(),
rtscore_text.get())
def delete_command():
"""Delete entry via button."""
backend.delete(selected_tuple[0])
def search_command():
"""Search entry via button."""
listing.delete(0, END)
for row in backend.search(title_text.get(),
director_text.get(),
year_text.get(),
studio_text.get(),
runtime_text.get(),
rtscore_text.get()):
listing.insert(END, row)
def get_selected_row(event):
"""Pre-fill fields for selected entry."""
global selected_tuple
index = listing.curselection()[0]
selected_tuple = listing.get(index)
entry1.delete(0, END)
entry1.insert(END, selected_tuple[1])
film = selected_tuple[1]
entry2.delete(0, END)
entry2.insert(END, selected_tuple[2])
entry3.delete(0, END)
entry3.insert(END, selected_tuple[3])
entry4.delete(0, END)
entry4.insert(END, selected_tuple[4])
entry5.delete(0, END)
entry5.insert(END, selected_tuple[5])
entry6.delete(0, END)
entry6.insert(END, selected_tuple[6])
def get_trailer():
global selected_tuple
index = listing.curselection()[0]
selected_tuple = listing.get(index)
film = selected_tuple[1]
year = selected_tuple[3]
years = str(year)
print(year)
print(film)
query_string = urllib.parse.urlencode({"search_query" : film + years + 'trailer'})
html_content = urllib.request.urlopen("http://www.youtube.com/results?" + query_string)
search_results = re.findall(r'href=\"\/watch\?v=(.{11})', html_content.read().decode())
web = ("http://www.youtube.com/watch?v=" + search_results[0])
print(web)
webbrowser.open(web)
window = Tk()
window.wm_title("Film Directory")
# Labels for entry fields.
label1 = Label(window, text = "Title")
label1.grid(row = 0, column = 0)
label2 = Label(window, text = "Director")
label2.grid(row = 0, column = 2)
label3 = Label(window, text = "Year")
label3.grid(row = 1, column = 0)
label4 = Label(window, text = "Studio")
label4.grid(row = 1, column = 2)
label5 = Label(window, text = "RunTime")
label5.grid(row = 2, column = 0)
label6 = Label(window, text = "RtScore")
label6.grid(row = 2, column = 2)
# Entry Fields.
title_text = StringVar()
entry1 = Entry(window, textvariable = title_text)
entry1.grid(row = 0, column = 1)
director_text = StringVar()
entry2 = Entry(window, textvariable = director_text)
entry2.grid(row = 0, column = 3)
year_text = StringVar()
entry3 = Entry(window, textvariable = year_text)
entry3.grid(row = 1, column = 1)
studio_text = StringVar()
entry4 = Entry(window, textvariable = studio_text)
entry4.grid(row = 1, column = 3)
runtime_text = StringVar()
entry5 = Entry(window, textvariable = runtime_text)
entry5.grid(row = 2, column = 1)
rtscore_text = StringVar()
entry6 = Entry(window, textvariable = rtscore_text)
entry6.grid(row = 2, column = 3)
# List all data.
listing = Listbox(window, height = 6, width = 35)
listing.grid(row = 2, column = 0, rowspan = 6, columnspan = 2)
# Scrollbar.
scroller = Scrollbar(window)
scroller.grid(row = 2, column = 2, rowspan = 6)
# Configure scrollbar for Listbox.
listing.configure(yscrollcommand = scroller.set)
scroller.configure(command = listing.yview)
listing.bind('<<ListboxSelect>>', get_selected_row)
# Buttons for various operations on data.
button1 = Button(window,
text = "View All",
width = 12,
command = view_command)
button1.grid(row = 3, column = 3)
button2 = Button(window,
text = "Search Entry",
width = 12,
command = search_command)
button2.grid(row = 4, column = 3)
button3 = Button(window,
text = "Add Entry",
width = 12,
command = add_command)
button3.grid(row = 5, column = 3)
button4 = Button(window,
text = "Update Selected",
width = 12,
command = update_command)
button4.grid(row = 6, column = 3)
button5 = Button(window,
text = "Delete Selected",
width = 12,
command = delete_command)
button5.grid(row = 7, column = 3)
button6 = Button(window,
text = "Close",
width = 12,
command = window.destroy)
button6.grid(row = 8, column = 3)
button7 = Button(window,
text = "Trailer",
width = 12,
command = get_trailer)
button7.grid(row = 9, column = 3)
# Keep window open until closed.
window.mainloop()
答案 0 :(得分:0)
Gui更新了运行时和rt_score条目 你的后端使用数据库访问不是。
我更新并修复了有限的测试,你可以 修复任何未完成或获得进一步帮助。
我将运行时列设置为数据库中的文本,您可以 如果不合适,请更改类型。
在主tk脚本中,函数中发生错误
get_selected_row
。我添加了一个临时解决方案,可能是tk
需要一个设置来避免这个问题。请参阅脚本注释。
您可能需要重新创建或更改现有数据库文件 backend.py将创建并使用另外2列的表。
tk脚本
from tkinter import *
import backend
import urllib.request
import urllib.parse
import re
import webbrowser
def add_command():
"""Insert entry via button."""
backend.insert(title_text.get(),
director_text.get(),
year_text.get(),
studio_text.get(),
runtime_text.get(),
rtscore_text.get())
listing.delete(0, END)
listing.insert(END,
(title_text.get(),
director_text.get(),
year_text.get(),
studio_text.get(),
runtime_text.get(),
rtscore_text.get()))
def view_command():
"""View entries via button."""
listing.delete(0, END)
for row in backend.view():
listing.insert(END, row)
def update_command():
"""Update entry via button."""
backend.update(selected_tuple[0],
title_text.get(),
director_text.get(),
year_text.get(),
studio_text.get(),
runtime_text.get(),
rtscore_text.get())
def delete_command():
"""Delete entry via button."""
backend.delete(selected_tuple[0])
def search_command():
"""Search entry via button."""
listing.delete(0, END)
for row in backend.search(title_text.get(),
director_text.get(),
year_text.get(),
studio_text.get(),
runtime_text.get(),
rtscore_text.get()):
listing.insert(END, row)
def get_selected_row(event):
"""Pre-fill fields for selected entry."""
global selected_tuple
# *** unsure fix to avoid index out of range error.
# *** callback issue when double click in a input ctrl.
if not listing.curselection(): return
index = listing.curselection()[0]
selected_tuple = listing.get(index)
entry1.delete(0, END)
entry1.insert(END, selected_tuple[1])
film = selected_tuple[1]
entry2.delete(0, END)
entry2.insert(END, selected_tuple[2])
entry3.delete(0, END)
entry3.insert(END, selected_tuple[3])
entry4.delete(0, END)
entry4.insert(END, selected_tuple[4])
entry5.delete(0, END)
entry5.insert(END, selected_tuple[5])
entry6.delete(0, END)
entry6.insert(END, selected_tuple[6])
def get_trailer():
global selected_tuple
index = listing.curselection()[0]
selected_tuple = listing.get(index)
film = selected_tuple[1]
year = selected_tuple[3]
years = str(year)
print(year)
print(film)
query_string = urllib.parse.urlencode({"search_query" : film + years + 'trailer'})
html_content = urllib.request.urlopen("http://www.youtube.com/results?" + query_string)
search_results = re.findall(r'href=\"\/watch\?v=(.{11})', html_content.read().decode())
web = ("http://www.youtube.com/watch?v=" + search_results[0])
print(web)
webbrowser.open(web)
window = Tk()
window.wm_title("Film Directory")
# Labels for entry fields.
label1 = Label(window, text = "Title")
label1.grid(row = 0, column = 0)
label2 = Label(window, text = "Director")
label2.grid(row = 0, column = 2)
label3 = Label(window, text = "Year")
label3.grid(row = 1, column = 0)
label4 = Label(window, text = "Studio")
label4.grid(row = 1, column = 2)
label5 = Label(window, text = "RunTime")
label5.grid(row = 2, column = 0)
label6 = Label(window, text = "RtScore")
label6.grid(row = 2, column = 2)
# Entry Fields.
title_text = StringVar()
entry1 = Entry(window, textvariable = title_text)
entry1.grid(row = 0, column = 1)
director_text = StringVar()
entry2 = Entry(window, textvariable = director_text)
entry2.grid(row = 0, column = 3)
year_text = StringVar()
entry3 = Entry(window, textvariable = year_text)
entry3.grid(row = 1, column = 1)
studio_text = StringVar()
entry4 = Entry(window, textvariable = studio_text)
entry4.grid(row = 1, column = 3)
runtime_text = StringVar()
entry5 = Entry(window, textvariable = runtime_text)
entry5.grid(row = 2, column = 1)
rtscore_text = StringVar()
entry6 = Entry(window, textvariable = rtscore_text)
entry6.grid(row = 2, column = 3)
# List all data.
listing = Listbox(window, height = 6, width = 35)
listing.grid(row = 2, column = 0, rowspan = 6, columnspan = 2)
# Scrollbar.
scroller = Scrollbar(window)
scroller.grid(row = 2, column = 2, rowspan = 6)
# Configure scrollbar for Listbox.
listing.configure(yscrollcommand = scroller.set)
scroller.configure(command = listing.yview)
listing.bind('<<ListboxSelect>>', get_selected_row)
# Buttons for various operations on data.
button1 = Button(window,
text = "View All",
width = 12,
command = view_command)
button1.grid(row = 3, column = 3)
button2 = Button(window,
text = "Search Entry",
width = 12,
command = search_command)
button2.grid(row = 4, column = 3)
button3 = Button(window,
text = "Add Entry",
width = 12,
command = add_command)
button3.grid(row = 5, column = 3)
button4 = Button(window,
text = "Update Selected",
width = 12,
command = update_command)
button4.grid(row = 6, column = 3)
button5 = Button(window,
text = "Delete Selected",
width = 12,
command = delete_command)
button5.grid(row = 7, column = 3)
button6 = Button(window,
text = "Close",
width = 12,
command = window.destroy)
button6.grid(row = 8, column = 3)
button7 = Button(window,
text = "Trailer",
width = 12,
command = get_trailer)
button7.grid(row = 9, column = 3)
# Keep window open until closed.
window.mainloop()
backend.py脚本
import sqlite3
def connect():
"""Set up a connection with the database."""
conn_obj = sqlite3.connect("movies.db")
cur_obj = conn_obj.cursor()
cur_obj.execute("CREATE TABLE IF NOT EXISTS "
"movie (id INTEGER PRIMARY KEY, "
"title TEXT,"
"director TEXT,"
"year INTEGER,"
"studio INTEGER,"
"runtime TEXT,"
"rt_score INTEGER)")
conn_obj.commit()
conn_obj.close()
def insert(title, director, year, studio, runtime, rt_score):
"""Insert entry into database."""
conn_obj = sqlite3.connect("movies.db")
cur_obj = conn_obj.cursor()
cur_obj.execute("INSERT INTO movie "
"(title,director,year,studio,runtime,rt_score) "
"VALUES (?, ?, ?, ?, ?, ?)",
(title, director, year, studio, runtime, rt_score))
conn_obj.commit()
conn_obj.close()
def view():
"""View all database entries."""
conn_obj = sqlite3.connect("movies.db")
cur_obj = conn_obj.cursor()
cur_obj.execute("SELECT * FROM movie")
rows = cur_obj.fetchall()
conn_obj.close()
return rows
def update(id, title, director, year, studio, runtime, rt_score):
"""Update a database entry."""
conn_obj = sqlite3.connect("movies.db")
cur_obj = conn_obj.cursor()
cur_obj.execute("UPDATE movie "
"SET title = ?, "
"director = ?, "
"year = ?, "
"studio = ?, "
"runtime = ?, "
"rt_score = ? "
"WHERE id = ?",
(title, director, year, studio, runtime, rt_score, id))
conn_obj.commit()
conn_obj.close()
def delete(id):
"""Delete a database entry."""
conn_obj = sqlite3.connect("movies.db")
cur_obj = conn_obj.cursor()
cur_obj.execute("DELETE FROM movie "
"WHERE id = ?", (id,))
conn_obj.commit()
conn_obj.close()
def search(title="", director="", year="", studio="", runtime="", rt_score=""):
"""Search for a database entry."""
conn_obj = sqlite3.connect("movies.db")
cur_obj = conn_obj.cursor()
cur_obj.execute("SELECT * "
"FROM movie "
"WHERE title = ? "
"OR director = ? "
"OR year = ? "
"OR studio = ? "
"OR runtime = ?"
"OR rt_score = ?",
(title, director, year, studio, runtime, rt_score))
rows = cur_obj.fetchall()
conn_obj.close()
return rows
connect()