Sqlite和Python,等于后的通配符
我有以下代码Sqlite和Python,等于后的通配符,python,sqlite,Python,Sqlite,我有以下代码 def function(foo): #Function that counts records in db with SB = 0 and SO = foo #SO takes the values {0,1} SQL = """ SELECT Count(*) FROM EvaluatedPlays WHERE SB = 0 AND SO = ? "
def function(foo):
#Function that counts records in db with SB = 0 and SO = foo
#SO takes the values {0,1}
SQL = """ SELECT Count(*) FROM EvaluatedPlays
WHERE
SB = 0
AND SO = ?
"""
data = SQLfunctions.fetchSQL(SQL, foo)
#This queries the db with the above SQL and foo as a binding
return data
我的问题是,我可以为
foo
(某种通配符)使用一个值,它将计算所有记录,使SB=0
,即的值不重要吗?如果没有,我将不得不更正一个全新的查询来执行此操作,由于可读性和冗余问题,我不希望这样做。否,没有与所有值匹配的值
您可以将这两个查询合并为一个更复杂的查询,例如,一个类似的
而不是一个非通配符字符串或纯通配符字符串,或者类似于(?为NULL或SO=?)
的查询,该查询接受两次参数。但这些文件的可读性可能较低,而不是更高,并可能导致性能下降
在这种情况下,动态格式化SQL语句可能是合理的,因为您没有在任何用户数据中格式化SQL语句,也没有生成不同语句的开放式集合,只有两个特定的语句。因此:
SQL = """ SELECT Count(*) FROM EvaluatedPlays
WHERE
SB = 0"""
if foo is not None:
SQL += "AND SO = ?"
cursor.execute(SQL, [foo] if foo is not None else [])
您可以使SQL更复杂一些,因此它使用?
的方式没有任何效果,而不是完全不使用它,从而允许您无条件地传递参数。但这可能会让读者感到非常困惑
您可以找到更通用的方法来概括这一点,但是您必须小心不要打开SQL注入、语句组合爆炸(这可能会破坏数据库的语句缓存)等的大门
当然,您可以将基于参数值进行切换的逻辑推送到存储过程中(使用SQLite,这甚至可以只是脚本中的一个函数),但对于这样一个简单的用例,这可能是一个非常复杂的解决方案
因此,您经常会发现,只有两个不同的语句看起来更干净、可读性更强。虽然可以,而且冗余程度可能更低,但我实际上认为,使用单独的函数会使事情更可读。否则,您的一个函数会做两件不同的事情。@HankDitton:好吧,您可以为任何具有默认值参数(或*args
参数等)的Python函数使用相同的参数。这显然是一种折衷,而不是一种开闭式的回答。@abarnert是的,我并不是说一种方法肯定比另一种好。只是写两个函数没有什么错。@HankDitton:同意。或者,也许,即使它有一些“错误”,在某些情况下,所有其他选择都有很多错误,因此它仍然是正确的/明显的/类似于蟒蛇的做法。