gpt4 book ai didi

python - 如何在 %sql 查询中使用 python 列表

转载 作者:行者123 更新时间:2023-11-30 21:22:05 25 4
gpt4 key购买 nike

我正在使用 sql在 Jupyter notebook 中打包,我了解如何在查询中使用变量:

client = "Disney"
queryid = %sql SELECT * FROM mytable WHERE name = :client

我不明白的是如何将列表传递给我的查询,例如:

clients = ["Disney", "Netflix", "Sky"]
queryid = %sql SELECT * FROM mytable WHERE name in (:clients)

这引发了一个错误,表明我的 SQL 是错误的。在此设置中处理列表的方式是什么?

最佳答案

sqlite3 的演示案例:

In [1]: import sqlite3
In [2]: conn = sqlite3.connect('example.db')
In [3]: c = conn.cursor()
In [4]: c.execute('''CREATE TABLE stocks
...: (date text, trans text, symbol text, qty real, price real)''')
...:
...: # Insert a row of data
...: c.execute("INSERT INTO stocks VALUES ('2006-01-05','BUY','RHAT',100,35.1
...: 4)")
...:
...: # Save (commit) the changes
...: conn.commit()
...:
In [5]: # Larger example that inserts many records at a time
...: purchases = [('2006-03-28', 'BUY', 'IBM', 1000, 45.00),
...: ('2006-04-05', 'BUY', 'MSFT', 1000, 72.00),
...: ('2006-04-06', 'SELL', 'IBM', 500, 53.00),
...: ]
...: c.executemany('INSERT INTO stocks VALUES (?,?,?,?,?)', purchases)

我可以获取匹配多个字符串的值:

In [31]: c.execute('SELECT * FROM stocks WHERE symbol IN (?,?)',('IBM','RHAT'))
Out[31]: <sqlite3.Cursor at 0xaf703fa0>
In [32]: c.fetchall()
Out[32]:
[('2006-01-05', 'BUY', 'RHAT', 100.0, 35.14),
('2006-03-28', 'BUY', 'IBM', 1000.0, 45.0),
('2006-04-06', 'SELL', 'IBM', 500.0, 53.0)]

或使用 Parameter substitution for a SQLite "IN" clause 中的通用解决方案

In [33]: alist=['RHAT','IBM']
In [34]: c.execute('SELECT * FROM stocks WHERE symbol IN (%s)' %
...: ','.join('?'*len(alist)),
...: alist)
...:
Out[34]: <sqlite3.Cursor at 0xaf703fa0>
In [35]: c.fetchall()
Out[35]:
[('2006-01-05', 'BUY', 'RHAT', 100.0, 35.14),
('2006-03-28', 'BUY', 'IBM', 1000.0, 45.0),
('2006-04-06', 'SELL', 'IBM', 500.0, 53.0)]

c.execute('SELECT * FROM stocks WHERE symbol IN (:1,:2)',alist),可能还有其他形式。

另见:

sqlite3 "IN" clause

我假设 MYSQL%sql iterface 行为相同;但我没有安装这些。


使用适当的引号文字也可以工作(再次 sqlite3)

c.execute('SELECT * FROM stocks WHERE symbol IN ("IBM","RHAT")')

In [80]: 'SELECT * FROM stocks WHERE symbol IN (%s)'%','.join('"%s"'%x for x in alist)
Out[80]: 'SELECT * FROM stocks WHERE symbol IN ("RHAT","IBM")'
In [81]: c.execute(_)

所以我猜:

%sql SELECT * FROM stocks WHERE symbol IN ("IBM","RHAT")

即使某种形式的 (:....) 不起作用,也能起作用。


我安装了%sql

In [5]: %%sql
...: sqlite:///example.db
...:

Out[5]: 'Connected: None@example.db'
In [7]: %sql SELECT * from stocks
Done.
Out[7]:
[('2006-01-05', 'BUY', 'RHAT', 100.0, 35.14),
('2006-03-28', 'BUY', 'IBM', 1000.0, 45.0),
('2006-04-05', 'BUY', 'MSFT', 1000.0, 72.0),
('2006-04-06', 'SELL', 'IBM', 500.0, 53.0)]

In [9]: %sql SELECT * from stocks where symbol in ('IBM')
Done.
Out[9]:
[('2006-03-28', 'BUY', 'IBM', 1000.0, 45.0),
('2006-04-06', 'SELL', 'IBM', 500.0, 53.0)]

In [10]: %sql SELECT * from stocks where symbol in ('IBM','RHAT')
Done.
Out[10]:
[('2006-01-05', 'BUY', 'RHAT', 100.0, 35.14),
('2006-03-28', 'BUY', 'IBM', 1000.0, 45.0),
('2006-04-06', 'SELL', 'IBM', 500.0, 53.0)]

字符串格式化方法有效:

In [11]: alist=['RHAT','IBM']
In [12]: cmd='SELECT * FROM stocks WHERE symbol IN (%s)'%','.join('"%s"'%x for x
...: in alist)
In [13]: cmd
Out[13]: 'SELECT * FROM stocks WHERE symbol IN ("RHAT","IBM")'
In [14]: %sql $cmd
Done.
Out[14]:
[('2006-01-05', 'BUY', 'RHAT', 100.0, 35.14),
('2006-03-28', 'BUY', 'IBM', 1000.0, 45.0),
('2006-04-06', 'SELL', 'IBM', 500.0, 53.0)]

: 语法没有很好的文档记录。目前尚不清楚谁在实现它。 ($ 是标准的 Ipython 变量替换)。

In [18]: sym='IBM'
In [19]: %sql SELECT * from stocks where symbol in (:sym)
Done.
Out[19]:
[('2006-03-28', 'BUY', 'IBM', 1000.0, 45.0),
('2006-04-06', 'SELL', 'IBM', 500.0, 53.0)]

(:sym1,:sym2) 中的符号 有效

到目前为止,我还没有看到 %sql 使用传统 SQL 占位符语法的证据。


看起来您(?)在 github 上提交并关闭了一个问题,https://github.com/catherinedevlin/ipython-sql/issues/92

调整该解决方案以引用字符串:

In [74]: mystring = '({})'.format(','.join('"{}"'.format(e) for e in alist))
In [75]: mystring
Out[75]: '("RHAT","IBM")'
In [76]: %sql SELECT * from stocks where symbol in $mystring
Done.

换句话说,使用 ipython $ 注入(inject)而不是 : 形式。


查看ipython-sql源码:

ipython-sql/blob/master/src/sql/run.py
def run(conn, sql, config, user_namespace):
...
txt = sqlalchemy.sql.text(statement)
result = conn.session.execute(txt, user_namespace)

看起来 :name 语法是一个 sqlalchemy 绑定(bind)参数,由 sqlalchemy.sql.text 处理sqlalchemy.sql.bind参数

( http://docs.sqlalchemy.org/en/latest/orm/tutorial.html#orm-tutorial-literal-sql )

此错误表明每个绑定(bind)参数都被翻译成一个 ? 占位符,加上匹配的 parameters 条目:

In [96]: %sql SELECT * from stocks where symbol in :mystring
(sqlite3.OperationalError) near "?": syntax error [SQL: 'SELECT * from stocks where symbol in ?'] [parameters: ('("RHAT","IBM")',)]

所以我生成 IN (?,?,...) 以匹配列表长度的原始解决方案是正确的 SQL,即使它不适用于 sqlalchemy%sql

关于python - 如何在 %sql 查询中使用 python 列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45112501/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com