如何将Python字符串列表传递给SQL查询

5
如何将Python字符串列表传递给SQL查询,例如select * from table where name in (names_from_python_list),其中names_from_python_list是来自Python列表的逗号分隔字符串?
使用','.join(name for name in name_list)将列表中的所有名称组合成一个字符串。
 select * from table where name in ('john,james,mary')

然而,我想要做的是:

  select * from table where name in ('john','james','mary')

1
','.join('\'' + i + '\'' for i in name_list) - Olvin Roght
可能会取决于数据库和驱动程序。无论如何,基于安全原因,我不建议使用涉及字符串拼接的任何东西。 - bereal
你能提供连接数据库所使用的DB-API驱动程序以及从Python查询时所用的代码吗?正如一些人已经提到的那样,一些库提供了扩展可迭代参数的可能性,这就避免了执行字符串操作的需要。 - Mihai Chelaru
5个回答

3

您可以选择将元组传递到您的SQL查询中:

query = f"SELECT * FROM table WHERE name IN {tuple(names)}"
c.execute(query,conn)

相比于使用以下方法,它更加强大:

query = "SELECT * FROM table WHERE name IN (?,?)" 
c.execute(query,conn,params)

由于您没有收到错误信息,因此建议您检查以下几个方面:

OperationalError: (sqlite3.OperationalError) too many SQL variables

...在将大量变量传递到查询中时


然而,如果你的参数是由用户在一个网络应用程序中输入的,要小心SQL注入! - rdmolony
然而,如果你的参数是由用户在一个网络应用程序中输入的,那么要小心SQL注入! - undefined

3
建议不要重复造轮子,看看成熟的数据库库提供的本地解决方案。例如,psqycopg2允许注册适配器,以便处理列表(和其他序列)变得透明,您可以直接将列表作为查询参数传递。这是一个示例:https://chistera.yi.org/~dato/blog/entries/2009/03/07/psycopg2_sql_in.html。pymysql还提供了一组良好的内置转义字符,包括用于处理序列的转义字符,因此您不必担心手动格式化(容易出错),可以直接将元组用作IN语句的参数。例子:
>>> conn = pymysql.connect(host='localhost', user='root', password='root', db='test')
>>> c.execute('select * from hosts where ip in %s', (('ip1', 'ip2'),))
>>> c.fetchall()
((1, 'mac1', 'ip1'), (3, None, 'ip2'))

相信许多其他成熟的库/框架也提供类似的功能。

1
这可能取决于驱动程序的特点,但使用标准的DB API应该如下所示:
connection.execute('SELECT * FROM table WHERE name IN (?)', (names,))

有些驱动程序中,? 也可以是 :1%s 等等。

0
根据您使用的函数,问号(?)可以表示Python变量,例如:

*"select * from table where name in ?;", (list,))*


0

使用','进行连接,并用'括起所有内容(不要忘记在名称中也替换'\'进行转义):

"'" + "','".join(name.replace("'", r"\'") for name in name_list) + "'") + "'"

或者您可以使用str.format并获取列表的str(减去[],因此需要切片),使用这种方式将更改字符串周围的引号,即,如果字符串是'O\'Hara',它将被转换为"O'Hara"

query = 'select * from table where name in ({})'.format(str(name_list)[1:-1])

1
如果我的名字是 Scarlett O'Hara,更不用说 little Bobby Tables 了,那该怎么办? - bereal
@bereal 感谢你的留言,我已经修复了它。尽管 str(names)[1:-1] 自动用 "(反之亦然)包含具有 ' 的字符串,并且如果字符串同时具有两种情况,则会将其转义,但由于某些 RDBMS 不支持双引号字符串,我认为手动操作更好一些。 - DjaouadNM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接