如何为 SELECT 查询的 IN 子句传递参数以检索 pandas DataFrame?
How can I pass parameters for the IN clause of a SELECT query to retrieve a 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 注入 并使用参数化查询的方法。
首先,如果您将 pandas 与 SQLite 以外的任何数据库一起使用,您应该使用 SQLAlchemy。 SQL当您将 select()
对象传递给 pandas .read_sql_query()
方法时,Alchemy 将自动构建所需的 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
"""
尝试将参数传递给简单的 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 注入 并使用参数化查询的方法。
首先,如果您将 pandas 与 SQLite 以外的任何数据库一起使用,您应该使用 SQLAlchemy。 SQL当您将 select()
对象传递给 pandas .read_sql_query()
方法时,Alchemy 将自动构建所需的 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
"""