如何为SELECT查询的IN子句传递参数以检索pandas DataFrame



尝试将参数传递给简单的SELECT查询:

query = """SELECT * from tbl_tab where name in {};"""

我通过这段代码来操作我的数据帧,其想法是能够将1到n个参数传递到我的查询中:

conn = pyodbc.connect(conx_string)
t = tuple(["N","M"])
crsr = conn.cursor()
data = crsr.execute(query.format(t))
rows = [list(x) for x in data]
columns = [column[0] for column in crsr.description]
df = pd.DataFrame(rows, columns=columns)

我得到了预期的结果。但是,当将单个参数传递给t:具有t = tuple(["N"])

我弄错了ProgrammingError: ('42000', "[42000] [Microsoft][ODBC SQL Server Driver][SQL Server]Incorrect syntax near ')'. (102) (SQLExecDirectW)")

你知道吗?

您正在使用元组的字符串表示将注入到SQL语句中。它适用于tuple(["N","M"]),因为您得到了… IN ('N', 'M')。但是,对于tuple(["N"]),它失败了,因为结果是… IN ('N',),并且后面的逗号不是有效的SQL语法。考虑一种避免SQL注入并使用参数化查询的方法。

首先,如果您将panda与SQLite以外的任何数据库一起使用,那么您应该使用SQLAlchemy。当您将select()对象传递给Panda.read_sql_query()方法时,SQLAlchemy将自动构建所需的SQL语句:

import pandas as pd
import sqlalchemy as sa
engine = sa.create_engine(
"mssql+pyodbc://scott:tiger^5HHH@mssql_199",
)
tbl_tab = sa.Table("tbl_tab", sa.MetaData(), autoload_with=engine)
# full contents of table:
with engine.begin() as conn:
print(conn.execute(sa.select(tbl_tab)).fetchall())
# [(1, 'Alicia'), (2, 'Brandon'), (3, 'Candace')]
# retrieve subset of rows into a DataFrame
name_list = ["Alicia", "Brandon"]
my_select = sa.select(tbl_tab).where(tbl_tab.c.name.in_(name_list))
df = pd.read_sql_query(my_select, engine)
print(df)
"""
id     name
0   1   Alicia
1   2  Brandon
"""

相关内容

  • 没有找到相关文章

最新更新