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

时间:2017-02-08 20:50:32

标签: python sql-server sqlalchemy pyodbc

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

x = ['1000000000164774783','1000000000253252111']

我使用 sqlalchemy pyodbc 连接到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")

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

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

所有这些似乎都将其转换为数字格式

(1000000000164774783, 1000000000253252111) instead of ('1000000000164774783','1000000000253252111')

因此查询失败,因为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)']

4 个答案:

答案 0 :(得分:4)

正如对其他答案的评论所述,该方法可能因各种原因而失败。你真正想做的是创建一个带有所需参数占位符数量的SQL语句,然后使用params= 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)

答案 1 :(得分:0)

sqlalchemey, pyodbc与熊猫read_sql()一起工作是一件令人毛骨悚然的事情。经过许多挫折并遇到pandaspsycopg的各种解决方案和文档之后,这是使用命名参数进行查询的正确方法(到目前为止):

import pandas as pd
import psycopg2
# import pyodbc 
import sqlalchemy
from sqlalchemy import text # this is crucial

cnx=sqlalchemy.create_engine(...)
x = ['1000000000164774783','1000000000253252111']
sql = "select * from Pretty_Txns where Send_Customer in (:id);" # named parameter
df = pd.read_sql(text(sql), cnx, params={'id':x}) # note how `sql`
                                                   # string is cast with text() 
                                                   # and key-pair value is passed for 
                                                   # named parameter 'id'
df.head()

我已经使其与PostgreSQL数据库一起使用。我希望MySQL不会有太大的不同。

答案 2 :(得分:0)

这是您需要的 SQL 查询

sql = f"select * from Pretty_Txns where Send_Customer in {tuple(x)}"
df = pd.read_sql(sql,cnx)

答案 3 :(得分:-1)

使用以下方法,它运行良好:

       sql = "select * from Pretty_Txns where Send_Customer in %s" % str(tuple(x))
      df = pd.read_sql(sql,cnx)