我正在开展一个小型宠物项目,该项目组织人们的漫画书并在SQL数据库中存储有关它们的元数据。为了正确起见,我使用预处理语句而不是Python内置的字符串运算符,但我无法让它正常工作。这是我用来说明我遇到的问题的简短代码片段:
#!/usr/bin/env python
import sqlite3
connection = sqlite3.connect("MyComicBox.db")
curs = connection.cursor()
curs.execute("CREATE TABLE IF NOT EXISTS comic_collection (id INTEGER PRIMARY KEY, series TEXT, publisher TEXT, issue TEXT, tags TEXT)")
connection.commit()
def addComic(series = "", publisher = "", issue = "", tags = ""):
curs.execute("INSERT INTO comic_collection (series, publisher, issue, tags) VALUES(?, ?, ?, ?)", (series, publisher, issue, tags))
connection.commit()
def search(attribute, val):
"""
Do an SQL query for all comics where attribute LIKE val and return a list of them.
"""
# cmd = "SELECT * from comic_collection WHERE %s LIKE '%s'" % (attribute, val)
# curs.execute(cmd)
cmd = "SELECT * from comic_collection WHERE ? LIKE ?"
curs.execute(cmd, (attribute, val))
results = []
for comic in curs:
results.append(comic)
return results
addComic(series = "Invincible Iron Man", issue = "500", publisher = "Marvel Comics", tags = "Iron Man; Spider-Man; Mandarin")
searchResults = search("issue", "500")
for item in searchResults:
print item
我的问题在于搜索功能。查询不会返回任何内容,除非我替换我执行cmd的两行使用?运算符有两条(已注释掉的)行,我使用Python的内置字符串运算符执行cmd。任何人都可以帮我弄清楚我做错了什么?
答案 0 :(得分:7)
您不能对列名使用占位符 - 它们仅用于值。所以这会奏效:
cmd = "SELECT * from comic_collection WHERE %s LIKE ?" % attribute
curs.execute(cmd, (val,))
答案 1 :(得分:2)
您对attribute
的使用是错误的。想象一下,?
已经包含了它的趋势''
。
一种方法是这样做:
cmd = "SELECT * from comic_collection WHERE %s LIKE ?" % attribute
curs.execute(cmd, val)
但你必须确保该属性不是来自不受信任的来源,或者它只有有效值,可能是
assert attribute in ('series', 'publisher', 'issue', 'tags')
答案 2 :(得分:-2)
从我回忆起sqlite C api中的预处理语句,您可能必须这样写:
cmd =“SELECT * from comic_collection WHERE?1 LIKE?2”