简体   繁体   English

如何将字符串的python列表传递给sql查询

[英]How to pass python list of string to sql query

How to pass a python list of strings to SQL query such as select * from table where name in (names_from_python_list) where names_from_python_list is comma separated strings from python list?如何将 python 字符串列表传递给 SQL 查询,例如select * from table where name in (names_from_python_list) where names_from_python_list是来自 python 列表的逗号分隔字符串?

Doing ','.join(name for name in name_list) gives all the names in the list as a string ie执行','.join(name for name in name_list)将列表中的所有名称作为字符串,即

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

whereas, what I want to do is:而我想做的是:

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

Rather than reinventing the wheel I'd suggest looking at native solutions mature db libraries provide.我建议不要重新发明轮子,而是查看成熟的数据库库提供的本机解决方案。

psqycopg2 eg allows registering adapter so that handling lists (and other sequences) becomes transparent, you can just directly pass list as a query parameter. psqycopg2 例如允许注册适配器,以便处理列表(和其他序列)变得透明,您可以直接将列表作为查询参数传递。 Here's an example: https://chistera.yi.org/~dato/blog/entries/2009/03/07/psycopg2_sql_in.html这是一个例子: https : //chistera.yi.org/~dato/blog/entries/2009/03/07/psycopg2_sql_in.html

pymysql also provides a good set of built-in escapers including one for dealing with sequences so that you don't have to worry about manual formatting (which is error-prone) and can directly use tuple as argument in IN clause. pymysql 还提供了一组很好的内置转义符,包括一个用于处理序列的转义符,这样您就不必担心手动格式化(容易出错),并且可以直接在 IN 子句中使用元组作为参数。 Example:例子:

>>> 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'))

Pretty sure many other mature libraries/frameworks provide similar functionality.可以肯定的是,许多其他成熟的库/框架都提供了类似的功能。

Join by ',' , and enclose everything by ' (don't forget to also replace ' in names with \\' to escape them):加入',' ,并用'括起所有内容(不要忘记将名称中的'也替换为\\'以转义它们):

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

Or you can just use str.format and get the str of the list (minus the [] , hence the slicing), using this way will change the quotations surrounding the string, ie, if the string is 'O\\'Hara' , it will be transformed to "O'Hara" :或者您可以只使用str.format并获取列表的str (减去[] ,因此切片),使用这种方式将更改字符串周围的引号,即,如果字符串是'O\\'Hara' ,它将被转换为"O'Hara"

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

This may depend on the driver peculiarities, though with standard DB API it should look like:这可能取决于驱动程序的特性,尽管使用标准 DB API 应该如下所示:

connection.execute('SELECT * FROM table WHERE name IN (?)', (names,))

With some drivers ?有一些司机? may also be :1 , %s etc.也可能是:1%s等。

Depending on what function you are using, ?根据您使用的功能,? can represent a python variable like.可以代表一个python变量,比如。

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

You can alternatively pass a tuple into your SQL query:您也可以将元组传递到您的 SQL 查询中:

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

It's also more robust than using:它也比使用更健壮:

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

As you don't get the error...由于您没有收到错误...

OperationalError: (sqlite3.OperationalError) too many SQL variables

... when passing a large number of variables into the query ... 将大量变量传递给查询时

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM