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数据框中?
您需要使用params 关键字参数:
f = pd.read_sql_query('SELECT open FROM NYSEMSFT WHERE date = (?)', conn, params=(date,))
Run Code Online (Sandbox Code Playgroud)
正如@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)