【问题标题】:MySQL and PYTHON. How to query an WHERE 'column' IN tupleMySQL 和 Python。如何在元组中查询 WHERE 'column'
【发布时间】:2016-03-21 19:54:34
【问题描述】:

我有一个整数元组,我想查询在元组中找到列值的所有行。构造查询很容易,但我希望它是 sql 注入证明。我通常使用准备好的语句,但我不知道如何处理这两种需求。

我的查询结构是这样的:

filterList = (1, 2, 4) #Taken as input. Should be integers

sqlRequest = 'SELECT * FROM table'
    if filterList != None and len(filterList) > 0:
        sqlRequest += ' WHERE column IN ('
        addComa = False
        for filter in filterList:
            if addComa:
                sqlRequest += ','
            else:
                addComa = True
            sqlRequest += '%s'%(int(filter)) #casted to int to avoid SQL injection. Still not as good as I would like
        sqlRequest += ')'

    #At this point sqlRequest == 'SELECT * FROM table WHERE column IN (1,2,4)'
    sqlResult = cursor.execute(sqlRequest)

我希望有一个更像的查询:

sqlRequest = 'SELECT * FROM table WHERE column IN (%s, %s, %s)'

并使用准备好的语句执行它:

sqlResult = cursor.execute(sqlRequest, filterList[0], filterList[1], filterList[2])

但 filterList 是可变长度的。有没有办法做类似的事情?

sqlResult = cursor.execute(sqlRequest, filterList) #where filterList is the whole tuple

【问题讨论】:

标签: python mysql python-2.7 tuples


【解决方案1】:

您可以使用字符串格式来生成占位符:

statement = "SELECT * FROM table WHERE column IN ({0})".format(
    ', '.join(['%s'] * len(filterList)))
cursor.execute(statement, filterList)

您可能仍想测试 filterList 不为空,并在这种情况下完全省略 WHERE 子句:

statement = "SELECT * FROM table"
if filterList:
    statement += " WHERE column IN ({0})".format(
        ', '.join(['%s'] * len(filterList)))
cursor.execute(statement, filterList)

【讨论】:

    【解决方案2】:

    你应该能够像这样将它作为一个完整的字符串插入到 mysql in 子句中。

    inList = "','".join(str(i) for i in filterList)
    inList = r"'%s'" % inList
    sqlRequest = 'SELECT * FROM table WHERE column IN (%s)'
    sqlResult = cursor.execute(sqlRequest, inList)
    

    【讨论】:

    • 否,因为这 SQL 引号 是逗号分隔的字符串。如果filterList['foo', 'bar', 'baz'],您现在将行限制为column 等于一个字符串且值为'foo,bar,baz' 的行。
    • 糟糕,我对其进行了编辑,使其成为原始字符串。
    • 不,您误解了原始字符串的作用。并且数据库适配器使用%s占位符来引用inList中的字符串值,以防止sql注入攻击(并作为sqlRequest查询计划的性能改进机会缓存独立于参数值)。我现在注意到第二个错误,execute() 的第二个参数必须是一个序列;你传入了一个字符串,所以每个单独的字符现在都是一个参数值。
    • 原始字符串只是语法,以与'...' 相同的方式生成字符串对象,但减去以常规语法解释\... 转义序列。
    猜你喜欢
    • 2021-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-17
    • 2022-08-02
    • 2023-04-06
    相关资源
    最近更新 更多