我得到了一个任意长度的Python列表,其中包含任意字符串。特别是,它可以具有带有嵌入式单引号和/或双引号的字符串。我无法控制输入,因此我必须接受给出的信息。
例如:
valueList = [ "hello'world", 'foo"bar', 'my\'name"is', "see\'you\"soon" ]
Python shell:
>>> valueList = [ "hello'world", 'foo"bar', 'my\'name"is', "see\'you\"soon" ]
>>>
>>> valueList
["hello'world", 'foo"bar', 'my\'name"is', 'see\'you"soon']
>>>
>>> valueList[0]
"hello'world"
>>>
>>> valueList[1]
'foo"bar'
>>>
>>> valueList[2]
'my\'name"is'
>>>
>>> valueList[3]
'see\'you"soon'
由此,我需要生成一个SQL字符串,例如:
"SELECT * FROM myTable as mt
WHERE mt."colName" IN ("hello'world", 'foo"bar', 'my\'name"is', 'see\'you"soon')
任何解决方案都必须与SQLite和Postgres一起使用。
我已经尝试使用Python join生成子句的(...)部分,但最终只是用一个大的字符串将所有单引号转义了。例如:
Python shell:
>>> values = "','".join(valueList)
>>> values
'hello\'world\',\'foo"bar\',\'my\'name"is\',\'see\'you"soon'
>>> values = "'" + "','".join(valueList) + "'"
>>> values
'\'hello\'world\',\'foo"bar\',\'my\'name"is\',\'see\'you"soon\''
附加信息:我继承的代码使用SQLAlchemy和Pandas。
import pandas as pd
...cut...cut...cut...
my_df = pd.read_sql(sql, my_conn);
我不想使用Pandas进行过滤。实际上,我的任务是删除现有的Pandas过滤器,并使用带有显式WHERE / IN过滤器的SQL替换它以提高速度。
例如,替换为:
my_df = pd.read_sql("SELECT * FROM myTable", my_conn) <==== can return 10's of thousands of rows
my_df = my_df[my_df.loc[:, 'colName'].isin(myList)] <==== ends up with a handful of rows
带有此:
my_df = pd.read_sql("SELECT * FROM myTable as mt WHERE mt."colName" IN ("hello'world", 'foo"bar', ...)", my_conn)
SQL注入保护是一个加号,但在这一点上,我将对任何可行的解决方案感到满意。
嗯,基于SQL规范,该规范将字符串文字定义为用单引号分隔,并且要包含单引号,则必须将字符串文字加倍(可以参考Sqlite和PostgreSQL的语法规范以确保它们符合该规范)这是我的尝试:
value_list = [ "hello'world", 'foo"bar', """my'name"is""", """see'you"soon""" ]
value_list_escaped = [f"""'{x.replace("'", "''")}'""" for x in value_list]
query_template = "SELECT * FROM myTable as mt WHERE mt.colName IN ({})"
query = query_template.format(", ".join(value_list_escaped))
print(query)
这就是您想要的吗?