我注意到大多数消息来源说在Python中执行SQL语句的最佳实践是这样的:
cursor.execute( 'select * from coworkers where name = :1 and clue > :2', [ name, clue_threshold ] )
其他消息来源说
cursor.execute( "select * from coworkers where name = %s and clue > %s", ( name, clue_threshold ) )
我觉得非常相似。
无论如何,我一直在做的方法是创建一个字典并存储值。例如,初始字典biz_info
如下所示:
biz_info = {
'business' : None,
'name' : None,
'neighborhood' : None,
'address' : None,
'city' : None,
'state' : None,
'zip_code' : None,
'latitude' : None,
'longitude' : None,
'phone' : None,
'url' : None,
'yelp_url' : None,
}
然后我像这样执行SQL语句
execute_sql( cur, "insert into " + TABLE_BIZ_NAME + """ values (
NULL,
%(name)s,
%(neighborhood)s,
%(address)s,
%(city)s,
%(state)s,
%(zip_code)s,
%(latitude)s,
%(longitude)s,
%(phone)s,
%(url)s,
%(yelp_url)s,
NULL
)"""
, biz_info )
这对sql注入是否安全?我想使用词典来存储信息,因为它更容易管理。
说实话,我甚至不确定使用%
,,
,%s
,%d
和%()s
之间的区别表示参数化查询。基本上我所知道的是不来使用
cursor.execute( "select * from coworkers where name = '%s' and clue > %d" % ( name, clue_threshold ) )
答案 0 :(得分:3)
用于将参数传递给sql命令字符串的方式取决于数据库(例如,sqlite使用?
)。
根据MySQLdb documentation,您可以使用paramstyle
参数设置格式化字符串的首选方式(format
或pyformat
)。
您的问题中的第一个示例似乎不受支持。无论如何,我会说,只要你不像上一个例子那样格式化整个字符串,你就可以安全,因为可以假设查询参数将被正确转义。
答案 1 :(得分:1)
您的insert语句应该明确指定要设置的字段名称,以防止从架构更改中断。此外,我发现你的代码太重复了。我会写插入更像这样的东西:
cursor.execute \
(
"insert into "
+
TABLE_BIZ_NAME
+
"("
+
", ".join(biz_info.keys())
+
") values ("
+
", ".join(("%s",) * len(biz_info))
+
")",
biz_info.values()
)
这样,在创建biz_info dict时,只需要列出一次字段名称。任何未来的变化只需要在那里进行更新。