2010-06-28 143 views
19

我很难在python中获得一些sql来正确地通过MySQLdb。这是pythons字符串格式,这是杀了我。带有SQL通配符和喜欢的Python字符串格式

我的sql语句使用LIKE关键字和通配符。我在Python中尝试了许多不同的东西。问题是一旦我得到其中一个工作,MySQLdb中有一行代码以字符串格式进行打包。

尝试1:

"SELECT tag.userId, count(user.id) as totalRows FROM user INNER JOIN tag ON user.id = tag.userId WHERE user.username LIKE '%%s%'" % (query)

这是一个没有去。我得到的值错误:

ValueError: unsupported format character ''' (0x27) at index 128

尝试2:

"SELECT tag.userId, count(user.id) as totalRows FROM user INNER JOIN tag ON user.id = tag.userId WHERE user.username LIKE '\%%s\%'" % (query)

我从尝试1.

尝试3相同的结果:

like = "LIKE '%" + str(query) + "%'" totalq = "SELECT tag.userId, count(user.id) as totalRows FROM user INNER JOIN tag ON user.id = tag.userId WHERE user.username " + like

这正确创建totalq变量,但现在当我去运行查询时,我从MySQLdb中收到错误:

File "build/bdist.macosx-10.6-universal/egg/MySQLdb/cursors.py", line 158, in execute query = query % db.literal(args) TypeError: not enough arguments for format string

尝试4:

like = "LIKE '\%" + str(query) + "\%'" totalq = "SELECT tag.userId, count(user.id) as totalRows FROM user INNER JOIN tag ON user.id = tag.userId WHERE user.username " + like

这是企图3.

输出相同的这一切似乎真的很奇怪。如何在python中使用sql语句中的通配符?

+0

要echo @bernie below:From psycopg docs:http://initd.org/psycopg/docs/usage.html#the-problem-with-the-query-parameters:“绝不,永远不要使用Python字符串连接(+)或字符串参数插值(%)将变量传递给SQL查询字符串。 “除了SQL注入攻击之外,第二个好处是驱动程序”可以自动将Python对象与SQL文字进行转换:使用此功能,您的代码将更加健壮和可靠“。这与”天真处理查询字符串的组成,例如使用字符串连接“ – 2013-06-10 13:21:09

回答

10

这不是字符串格式化,但问题是如何查询应根据在Python数据库操作要求(PEP 249

尝试这样执行:

sql = "SELECT column FROM table WHERE col1=%s AND col2=%s" 
params = (col1_value, col2_value) 
cursor.execute(sql, params) 

here are some examples for psycog2,你有一些解释那也应该对mysql有效(mysqldb也遵循PEP249 dba api指导2。0:here are examples for mysqldb

+0

谢谢。 MySQL数据库会计算出如何在sql语句中跳过参数,但是现在它可以像这样抛出参数。 – gngrwzrd 2010-06-28 18:07:57

+0

很高兴帮助你!我花了很多时间,直到我想到前一段时间:) – dzida 2010-06-28 21:12:11

6

为了逃避Python中的字符串格式化表达式&符号,双符号:

'%%%s%%' % search_string 

编辑:但我绝对有另一个答案一致。 SQL查询中的直接字符串替换几乎总是一个坏主意。

20

这些查询似乎都容易受到SQL注入攻击。

尝试这样代替:

curs.execute("""SELECT tag.userId, count(user.id) as totalRows 
        FROM user 
      INNER JOIN tag ON user.id = tag.userId 
       WHERE user.username LIKE %s""", ('%' + query + '%',)) 

如果有两个参数传递给​​。

+1

这看起来也容易受到SQL注入的影响,通过任何用于连接数据库的库来使用参数化查询都是最好的选择 – jrdioko 2010-06-28 17:45:43

+4

@jrdioko:感谢您的评论请注意,没有实际的字符串插值,并且查询*是由'execute()'方法准备的。 – bernie 2010-06-28 17:49:31

+0

我回过头来看,它的语法看起来就是这个库是如何实现参数化查询的。 – jrdioko 2010-06-28 17:51:45

-1

我有一个解决问题的方法:

不能使用:

"SELECT tag.userId, count(user.id) as totalRows FROM user INNER JOIN tag ON user.id = tag.userId WHERE user.username LIKE '%%s%'" % (query) 

你可以用串模板改变它,如:

import MySQLdb 
import string # string module 
....... 
value = {'user':'your value'} 
sql_template = string.Template(""" 
SELECT tag.userId, count(user.id) as totalRows FROM user INNER JOIN 
tag ON user.id = tag.userId WHERE user.username LIKE '%$user%' 
""") 

sql = sql_template.substitute(value) 

try: 
    cursor.execute(sql) 
    ........... 
except: 
    ........... 
finally : 
    db.close() 
+0

这不如直接替换,你不应该这样做。占位符如上所述,在PEP 249文档中描述如何正确地做到这一点 – Turk 2017-04-10 20:51:31