在 Python 中从字符串数组(或元组)创建动态 sql“in list”子句的“最佳”方法是啥? [复制]

Posted

技术标签:

【中文标题】在 Python 中从字符串数组(或元组)创建动态 sql“in list”子句的“最佳”方法是啥? [复制]【英文标题】:What's the "best" way to create a dynamic sql "in list" clause in Python from an array (or tuple) of strings? [duplicate]在 Python 中从字符串数组(或元组)创建动态 sql“in list”子句的“最佳”方法是什么? [复制] 【发布时间】:2016-01-13 15:21:38 【问题描述】:

我正在从 Python(使用 mysqlDb)运行一个动态 MySQL 查询,其中包括一个包含字符串值的“in list”子句。执行此操作的函数会获取一个值数组。如果有帮助,我可以将该数组制作成元组或任何其他类型的集合。

插入此列表的“最佳”方式是什么?请记住,需要单引号和逗号等。这是一个丑陋但安全的手动方法:

inList = ""
for stringValue in someArray:
    if inList != "" : inList += ","
    inList += "'%s'" % stringValue
querystr = "SELECT * FROM some_tbl WHERE some_column IN( %s );" % (inList) 

或者,这是另一种选择。它更短,但依赖于数组到字符串表示在未来保持完全相同:

inList = str(someArray).replace("[", "").replace("]", "")   
querystr = "SELECT * FROM some_tbl WHERE some_column IN( %s );" % (inList) 

编辑

我认为当我写这篇文章时我的 Python 术语是错误的。我应该说“列表”而不是“数组”。

【问题讨论】:

究竟有多安全?这是一个开放的 sql 注入漏洞。 请解释一下。这不是假设有人可以随心所欲地定义数组吗?通常如何构建动态 sql 语句? 问题不是构建动态 sql,而是以不安全的方式构建它。 “安全”是指“功能可靠”,顺便说一句... 好吧,考虑做一个名字列表:Miles O'Brien,然后变成where name in (Miles O'Brien)。哎呀。语法错误,查询已死,“完全可靠,伙计”。 【参考方案1】:

确实没有很好的方法来保证这种动态查询的安全。您应该切换到参数化查询,在这种情况下,解决方案是:

placeholder = '%s'
param_subs = ','.join((placeholder,) * len(param_list))
sql = 'SELECT col1, col2, . . . FROM Table WHERE Column IN ( %s );' % param_subs
cursor.execute(sql, param_list)

(假设您使用的是 MySQL 连接器,不幸的是,它使用 %s 作为占位符。其他 Python 库倾向于使用 ? 作为占位符。)

【讨论】:

这看起来是个好方法。为了清楚起见,“安全”是指防止坏字符,还是 sql 注入(正如 Mark B 指出的那样),或者其他什么?我很遗憾在我的问题中使用了那个“安全”的术语...... 我指的是两者,因为两者都来自同一个问题——我们在编写代码时无法知道将来作为参数提供的可能的值域。跨度> 也可以使用itertools.repeat 代替(placeholder,) * len(...)

以上是关于在 Python 中从字符串数组(或元组)创建动态 sql“in list”子句的“最佳”方法是啥? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

如何在 immutable.js 中定义字符串和数字数组或元组

Python怎么样把列表(list)或元组(tumple)转换为字符串

Python基础(3) - 去掉列表或元组中的重复元素

python-列表或元组去重

python 按升序对列表(或元组列表)进行排序

python之路-05-列表或元组