将值列表从Python传递到SQL查询的IN子句

opt*_*ime 2 python sql-server sqlalchemy pyodbc

我正在尝试将以下列表传递给sql查询

x = ['1000000000164774783','1000000000253252111']
Run Code Online (Sandbox Code Playgroud)

我正在使用sqlalchemypyodbc连接到sql:

import pandas as pd
from pandas import Series,DataFrame
import pyodbc
import sqlalchemy

cnx=sqlalchemy.create_engine("mssql+pyodbc://Omnius:MainBrain1@172.31.163.135:1433/Basis?driver=/opt/microsoft/sqlncli/lib64/libsqlncli-11.0.so.1790.0")
Run Code Online (Sandbox Code Playgroud)

我尝试使用各种字符串格式函数在sql查询中使用。下面是其中之一

  xx = ', '.join(x)
  sql = "select * from Pretty_Txns where Send_Customer in (%s)" % xx
  df = pd.read_sql(sql,cnx)
Run Code Online (Sandbox Code Playgroud)

他们似乎都将其转换为数字格式

(1000000000164774783, 1000000000253252111) instead of ('1000000000164774783','1000000000253252111')
Run Code Online (Sandbox Code Playgroud)

因此查询失败,因为SQL 中Send_Customer的数据类型为varchar(50)

 ProgrammingError: (pyodbc.ProgrammingError) ('42000', '[42000] [Microsoft][SQL Server Native Client 11.0]
  [SQL Server]Error converting data type varchar to numeric. (8114) (SQLExecDirectW)') 
 [SQL: 'select * from Pretty_Txns where Send_Customer in (1000000000164774783, 1000000000253252111)']
Run Code Online (Sandbox Code Playgroud)

Gor*_*son 6

如对其他答案的评论中所述,该方法可能由于多种原因而失败。您真正想要执行的操作是创建带有所需数量的参数占位符的SQL语句,然后使用params=参数of read_sql提供值:

x = ['1000000000164774783','1000000000253252111']
placeholders = ','.join('?' for i in range(len(x)))  # '?,?'
sql = "select * from Pretty_Txns where Send_Customer in (%s)" % placeholders
df = pd.read_sql(sql, cnx, params=x)
Run Code Online (Sandbox Code Playgroud)