Python 使用其他参数将列表绑定到Pandas read_sql_查询中的参数

Python 使用其他参数将列表绑定到Pandas read_sql_查询中的参数,python,pandas,pyodbc,Python,Pandas,Pyodbc,我一直在尝试测试各种使代码运行的方法。首先,我有以下清单: member_list=[111222333444555,…] 我试图将其传递到此查询中: query=pd.read\u sql\u查询( """ 选择成员id 年月 从查询的表 年和月之间在哪里?和? 会员身份证在哪? “”,db2conn,params=[201601,201603,成员列表]) 但是,我得到一个错误,它说: '无效的参数类型。参数索引=2参数类型=列表“HY105” 所以我环顾四周,尝试使用格式化字符串: qu

我一直在尝试测试各种使代码运行的方法。首先,我有以下清单:

member_list=[111222333444555,…]

我试图将其传递到此查询中:

query=pd.read\u sql\u查询(
"""
选择成员id
年月
从查询的表
年和月之间在哪里?和?
会员身份证在哪?
“”,db2conn,params=[201601,201603,成员列表])
但是,我得到一个错误,它说:

'无效的参数类型。参数索引=2参数类型=列表“HY105”

所以我环顾四周,尝试使用格式化字符串:

query=pd.read\u sql\u查询(
"""
选择成员id
年月
从查询的表
年和月之间在哪里?和?
和(%s)中的成员id
“”“%,”.join(“?”]*len(成员列表),db2conn,params=[201601,201603,元组(成员列表)])
现在,我得到一个错误:

'SQL包含18622个参数标记,但提供了3个参数''HY000'

因为它希望填充格式化字符串中的所有
占位符

那么,最终,是否有一种方法可以评估列表并传递每个单独的元素以绑定到
,或者是否有另一种方法可以让它工作

顺便说一句,我正在使用
pyodbc
作为我的连接器


提前感谢!

将其分为三个部分,以帮助隔离问题并提高可读性:

  • 构建SQL字符串
  • 设置参数值
  • 执行

  • 构建SQL 首先确保已正确设置了
    占位符。根据
    成员列表的长度,使用with和动态填写
    。下面的示例假设有3个
    成员列表的元素

    例子 退换商品
    设置参数值 现在,请确保将参数值组织到一个平面元组中

    例子 退换商品
    执行 最后,在
    read\u sql\u query
    调用中将
    sql
    params
    值放在一起

    query = pd.read_sql_query(sql, db2conn, params)
    

    如果您使用的是Python3.6+,您还可以在查询中使用格式化字符串literal(cf)


    Flatte函数成功了!!!但是,我想我只是遇到了一个参数cap的问题。显然,我的成员列表有84000多个成员,但是当我尝试动态填充所有这些成员的
    占位符时,Python限制了最大18622个。看起来我必须拆分我的成员列表才能做到这一点。谢谢你u帮助!很高兴提供帮助。由于您使用了那么多
    成员列表
    值,可能会获得更好的性能(并修复参数限制)通过填充另一个表,然后进行内部联接以筛选结果。这可能有助于创建表。对于
    pymysql
    ,您需要一个
    %s
    占位符,因此它应该是
    ,'。联接(['%s']*len(成员列表))
    Bryan的回答太棒了!不过需要注意的是,params默认不是pd.read\u sql\u查询中的第三个参数,因此只有在我指定params=params时,它才起作用:pd.read\u sql\u查询(sql,db2conn,params=params)更多:注意:“开始”和“结束”可能需要转换为字符串,具体取决于DB表中“yearmonth”列的类型……虽然您建议的方法可以工作,但不建议使用,因为它容易受到SQL注入攻击。确实存在轻微风险(但很多事情都会导致查询失败)。尽管如此,提议的解决方案并没有提供更多的安全性(只是通过使用join检查过去的列表是否可枚举)。我认为如果你做得足够深入,可能也会受到注入攻击……无论如何,首先我不清楚查询是否提供了前端指令;其次,验证输入的责任应该在包装该查询的函数中,而不是查询字符串本身……最后一件事,取决于使用的DB引擎,你可能会当元组由单个元素组成时,需要验证
    所选的\u成员
    元组。这是因为在python中,它将打印为
    (111,)
    ,而(至少通过psycopg2)只有在查询为
    (111)
    时才能成功解析查询。
    select member_id, yearmonth
    from queried_table
    where yearmonth between ? and ?
    and member_id in (?,?,?)
    
    # generator to flatten values of irregular nested sequences,
    # modified from answers http://stackoverflow.com/questions/952914/making-a-flat-list-out-of-list-of-lists-in-python
    def flatten(l):
        for el in l:
            try:
                yield from flatten(el)
            except TypeError:
                yield el
    
    params = tuple(flatten((201601, 201603, member_list)))
    print(params)
    
    (201601, 201603, 1, 2, 3)
    
    query = pd.read_sql_query(sql, db2conn, params)
    
    start, end = 201601, 201603
    selected_members = (111, 222, 333, 444, 555)  # requires to be a tuple
    
    query = f"""
        SELECT member_id, yearmonth FROM queried_table
        WHERE yearmonth BETWEEN {start} AND {end}
          AND member_id IN {selected_members}
    """
    
    df = pd.read_sql_query(query, db2conn)
    
    query = 'Select count(*) cnt from TBL_DESK_AUDIT  where trunc(DATETIMECREATED) = trunc(sysdate) and DESK_NAME =' + "'"+dataframe_list1[0][0] + "'"
    print(query)
    df_TBL_DESK_AUDIT = pd.read_sql_query(query, connect);