使用Pandas和pyodbc进行动态查询 - 寻找非字符串方法解决方案

时间:2017-11-17 02:57:34

标签: python-3.x pandas ms-access pyodbc

我正在编写一个脚本来动态查询MS Access数据库并将结果返回到pandas数据帧中。将有两个参数可动态更改查询。我使用字符串格式化方法组合了以下解决方案。虽然这个解决方案有效,但我正在寻找一种不使用字符串方法的更安全的解决方案。欣赏您可以分享的任何知识!

谢谢。

values1 = ('1','2')
values2 = ('1','2','3')

ServerName = r'pathtodb\\database.mdb'
connStr = 'DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=%s;' %ServerName
cnxn = pyodbc.connect(connStr)
query = 'SELECT * FROM TABLE WHERE item in ({0}) and item2 in ({1})'
query = query.format(','.join('?' * len(values1)), ','.join('?' * len(values2)))
param_list = values1 + values2
df = pd.read_sql_query(query, cnxn, params=param_list)
print(df)

1 个答案:

答案 0 :(得分:1)

考虑使用临时表, items1 items2 来保存值,然后只需加入pandas导入。实际上,JOIN方法比IN()子句中的长列表更有效。

values1 = ('1','2')
values2 = ('1','2','3')

ServerName = r'C:\pathtodb\database.mdb'
connStr = 'DRIVER={{Microsoft Access Driver (*.mdb, *.accdb)}};DBQ={0};'.format(ServerName)
cnxn = pyodbc.connect(connStr)

cur = cnxn.cursor()

# CLEAN OUT OLD DATA AND APPEND NEW DATA
cur.execute('DELETE FROM items1')
cnxn.commit()
cur.executemany('INSERT INTO items1 ([item]) VALUES (?)', values1)
cnxn.commit()

cur.execute('DELETE FROM items2')
cnxn.commit()
cur.executemany('INSERT INTO items2 ([item]) VALUES (?)', values2)
cnxn.commit()

# IMPORT JOIN QUERY INTO PANDAS (PARENTHESES ARE REQUIRED)
query = '''SELECT * FROM (TABLE t 
        INNER JOIN items1 i1 ON t.[item] = i1.[item])
        INNER JOIN items2 i2 ON t.[item2] = i2.[item]
'''

df = pd.read_sql_query(query, cnxn)
print(df)

替代查询:

query = '''SELECT * FROM TABLE 
        WHERE item IN (SELECT [item] FROM items1) 
          AND item2 IN (SELECT [item] FROM items2)
'''