Pandas Sqlite查询使用变量

Mus*_*ger 4 python sql sqlite pandas

使用Python中的sqlite3如果我想使用变量而不是固定命令进行数据库查询,我可以这样做:

name = 'MSFT'

c.execute('INSERT INTO Symbol VALUES (?) ', (name,))
Run Code Online (Sandbox Code Playgroud)

当我尝试使用pandas数据框访问SQL数据库时,我可以这样做:

df = pd.read_sql_query('SELECT open FROM NYSEXOM', conn) 
Run Code Online (Sandbox Code Playgroud)

但是,我不确定如何在引用变量时将数据从SQL加载到pandas数据框.我尝试过以下方法:

conn = sqlite3.connect('stocks.db')
dates= [20100102,20100103,20100104]
for date in dates:

    f = pd.read_sql_query('SELECT open FROM NYSEMSFT WHERE date = (?)', conn, (date,))
Run Code Online (Sandbox Code Playgroud)

当我运行这个时,我得到一个错误,说"提供的绑定数量不正确,当前语句使用1,并且提供了0"

如何使用变量引用正确格式化命令以将SQL数据加载到pandas数据框中?

ale*_*cxe 5

您需要使用params 关键字参数:

f = pd.read_sql_query('SELECT open FROM NYSEMSFT WHERE date = (?)', conn, params=(date,))
Run Code Online (Sandbox Code Playgroud)


Max*_*axU 5

正如@alecxe 和@Ted Petrou 已经说过的那样,使用显式参数名称,尤其是对于params参数,因为它是pd.read_sql_query()函数中的第四个参数,而您将其用作第三个参数(即)coerce_float

但除此之外,您可以通过for date in dates:使用以下技巧摆脱循环来改进代码:

import sqlite3

dates=['2001-01-01','2002-02-02']
qry = 'select * from aaa where open in ({})'

conn = sqlite3.connect(r'D:\temp\.data\a.sqlite')

df = pd.read_sql(qry.format(','.join(list('?' * len(dates)))), conn, params=dates)
Run Code Online (Sandbox Code Playgroud)

演示:

源 SQLite 表:

sqlite> .mode column
sqlite> .header on
sqlite> select * from aaa;
open
----------
2016-12-25
2001-01-01
2002-02-02
Run Code Online (Sandbox Code Playgroud)

测试运行:

In [40]: %paste
dates=['2001-01-01','2002-02-02']
qry = 'select * from aaa where open in ({})'
conn = sqlite3.connect(r'D:\temp\.data\a.sqlite')

df = pd.read_sql(qry.format(','.join(list('?' * len(dates)))), conn, params=dates)
## -- End pasted text --

In [41]: df
Out[41]:
         open
0  2001-01-01
1  2002-02-02
Run Code Online (Sandbox Code Playgroud)

解释:

In [35]: qry = 'select * from aaa where open in ({})'

In [36]: ','.join(list('?' * len(dates)))
Out[36]: '?,?'

In [37]: qry.format(','.join(list('?' * len(dates))))
Out[37]: 'select * from aaa where open in (?,?)'

In [38]: dates.append('2003-03-03')   # <-- let's add a third parameter

In [39]: qry.format(','.join(list('?' * len(dates))))
Out[39]: 'select * from aaa where open in (?,?,?)'
Run Code Online (Sandbox Code Playgroud)