Pyodbc:如何将元组作为查询参数传递?

Sup*_*tew 1 python sql ms-access pyodbc

快速概述:

这里的想法是从 csv 文件中读取一些数据,并将其用作我的 sql 查询部分中的列表NOT IN。我使用下面的代码连接到数据库(.mdb)。注意LP是我试图传递的元组/列表,IRdb是数据库的路径

constr = r'Driver={Microsoft Access Driver (*.mdb, *.accdb)};Dbq=' + IRdb
conn = pyodbc.connect(constr, autocommit=True)
cur = conn.cursor()

IRsql='''SELECT IRRPResults.RRPName, IRRPResults.PointName, IRRPResults.RiskPerTime FROM IRRPResults 
WHERE IRRPResults.PointName<>? 
AND IRRPResults.RRPName NOT LIKE ? AND IRRPResults.PointName NOT IN ?'''

cur.execute(IRsql,('Total',r'Conn%',LP))
Run Code Online (Sandbox Code Playgroud)

问题:

除了执行语句(在我添加该NOT IN部分之前它确实有效)之外,一切都工作正常。我尝试过LP作为字符串、元组和列表传递,但似乎没有任何效果。我收到以下错误

pyodbc.ProgrammingError: ('42000', "[42000] [Microsoft][ODBC Microsoft Access Driver] In operator without () in query expression 'IRRPResults.PointName<>Pa_RaM000 AND IRRPResults.RRPName NOT LIKE Pa_RaM001 AND IRRPResults.PointName NOT IN Pa_RaM002'. (-3100) (SQLExecDirectW)")
Run Code Online (Sandbox Code Playgroud)

任何帮助将不胜感激。

Sup*_*tew 8

对于任何感兴趣的人,或者两年后阅读本文并遇到同样问题的人,或者当我忘记自己做了什么时未来的自己,我已经想出了一两个解决方案。

第一个解决方法是简单地使用.formatsql 字符串在LP传递给执行语句之前直接插入。

IRsql='''SELECT IRRPResults.RRPName, IRRPResults.PointName, IRRPResults.RiskPerTime FROM IRRPResults 
WHERE IRRPResults.PointName<>? 
AND IRRPResults.RRPName NOT LIKE ? AND IRRPResults.PointName NOT IN {}'''.format(LP)

cur.execute(IRsql,('Total',r'Conn%'))
Run Code Online (Sandbox Code Playgroud)

我从这个问题中得到的另一个解决方案更加优雅和聪明,因为它构建了一串“?” LP 中每个元素的标记。然后 LP 作为元组/列表传递给执行语句。

placeholders=','.join('?'*len(LP))
IRsql='''SELECT IRRPResults.RRPName, IRRPResults.PointName, IRRPResults.RiskPerTime FROM IRRPResults 
WHERE IRRPResults.PointName<>? 
AND IRRPResults.RRPName NOT LIKE ? AND IRRPResults.PointName NOT IN ({})'''.format(placeholders)

cur.execute(IRsql,('Total',r'Conn%',*LP))
Run Code Online (Sandbox Code Playgroud)