【问题标题】:Pandas Sqlite query using variable使用变量的 Pandas Sqlite 查询
【发布时间】:2017-05-10 12:29:33
【问题描述】:

在 Python 中使用 sqlite3,如果我想使用变量而不是固定命令进行数据库查询,我可以执行以下操作:

name = 'MSFT'

c.execute('INSERT INTO Symbol VALUES (?) ', (name,))

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

df = pd.read_sql_query('SELECT open FROM NYSEXOM', conn) 

但是我不确定如何在引用变量时将数据从 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,))

当我运行它时,我收到一条错误消息“提供的绑定数量不正确,当前语句使用 1,并且提供了 0”

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

【问题讨论】:

  • 尝试将其更改为:` f = pd.read_sql_query('SELECT open FROM NYSEMSFT WHERE date = (?)', conn, params=(date,))`

标签: python sql sqlite pandas


【解决方案1】:

另一种选择是显式地使用 python 字符串格式并忘记 params 参数。也就是说你做这样的事情

conn = sqlite3.connect("database.sqlite")

df = pd.read_sql_query("                                           \
           SELECT * FROM table WHERE name= %s AND                  \
           number=%f" %(some_string_variable,some_float_variable)  \
           ,conn))

【讨论】:

  • 你不应该对 sql 语句进行字符串格式化,因为你的程序很容易受到 sql 注入攻击
【解决方案2】:

正如@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)

演示:

源 SQLite 表:

sqlite> .mode column
sqlite> .header on
sqlite> select * from aaa;
open
----------
2016-12-25
2001-01-01
2002-02-02

测试运行:

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

说明:

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 (?,?,?)'

【讨论】:

    【解决方案3】:

    您需要使用params关键字参数

    f = pd.read_sql_query('SELECT open FROM NYSEMSFT WHERE date = (?)', conn, params=(date,))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-05-14
      • 1970-01-01
      • 1970-01-01
      • 2015-08-01
      • 2018-04-25
      • 1970-01-01
      • 2014-01-05
      • 1970-01-01
      相关资源
      最近更新 更多