使用Python和SQLite进行关键字搜索
我有一个游戏服务器的插件,用来记录地图上的变化。数据库里有一些条目,格式是这样的:id 是一个整数并且是主键,matbefore 是一个整数,matafter 也是一个整数,name 是一个最多50个字符的字符串,date 是一个日期。我正在尝试创建一个函数,这个函数可以接收一个列名、一个整数、一个字符串,或者一个整数或字符串的元组,还有一个关键词,然后找到符合条件的条目。目前我写的代码是这样的 -
def readdb(self,keyword,column,returncolumn = "*"):
self.memwrite
if isinstance(keyword, int) or isinstance(keyword,str):
entry = [keyword]
qmarks = ("? OR " * len(entry))[:-4]
statement = 'SELECT all {0} FROM main WHERE {1} is {2}'.format(returncolumn,column,qmarks)
print(qmarks)
self.memcursor.execute(statement, entry)
return(self.memcursor.fetchall())
这里的关键词是要搜索的关键词,column 是要搜索的列,returncolumn 是要返回的列。我想知道为什么这段代码总是找不到任何行,比如说 - 返回 None,无论我在函数里输入什么。看起来如果我在控制台里直接执行这些操作是没问题的,但如果把它们放在函数里就不行了。
2 个回答
- 不太明白这段代码想干嘛。你是想用 self.memwrite() 吗?
def readdb(self,keyword,column,returncolumn = "*"): self.memwrite # 1. if isinstance(keyword, int) or isinstance(keyword,str): # 2. entry = [keyword] # 3. qmarks = ("? OR " * len(entry))[:-4] # 4. statement = 'SELECT all {0} FROM main WHERE {1} is {2}'.format(returncolumn,column,qmarks) print(qmarks) # 5. self.memcursor.execute(statement, entry) return(self.memcursor.fetchall())
可以改成
if isinstance(keyword, (int,str))
这样。或者更好的是,不要去检查类型。因为你写的代码里,keyword 不能是 Unicode 字符串。为什么要这样限制呢?在这种情况下,我觉得用
try...except...
结构来捕捉后面的错误会更好,而不是限制类型。- 所以最多
len(entry) = 1
。注意,如果 keyword 不是 int 或 str 类型,可能根本到不了这一行。那样的话,第 (4) 行会出错,因为 entry 还没有定义。 这段代码也可以写成
qmarks = ' OR '.join(['?']*len(entry))
这样可以避免在
("? OR " *1)[:-4]
中使用那个有点神秘的数字 4。你在这里看到了什么?如果是空的,那应该是个线索。此外,运行
print(statement)
可以更全面地了解传给.execute()
的内容。也许可以试试
statement = 'SELECT {0} FROM main WHERE {1} = ?'.format( returncolumn,column)
特别是,
is
应该改成=
。
如果 entry
是一个列表(就像昨天的问题那样),那么这个写法是行不通的。
>>> returncolumn = "*"
>>> column = "name"
>>> entry = ["Able", "Baker", "Charlie"]
>>> qmarks = ("? OR " * len(entry))[:-4]
>>> statement = 'SELECT all {0} FROM main WHERE {1} is {2}'.format(returncolumn,
column,qmarks)
>>> print statement
SELECT all * FROM main WHERE name is ? OR ? OR ?
SQLite 会看到的是:
SELECT all * FROM main WHERE name is 'Able' OR 'Baker' OR 'Charlie'
这不是正确的语法,因为你需要用 =
,而不是 is
。
即使你把这个问题修正了,比如用整数查询:
SELECT all * FROM main WHERE id = 1 or 2 or 3
你也会得到一些奇怪的结果,因为这实际上意味着 WHERE ((id = 1) or 2) or 3)
,而不是你想的那样……你需要写成 WHERE id = 1 or id = 2 or id = 3
,或者(回到昨天的问题) WHERE id IN (1,2,3)
。