使用MySQLdb执行“SELECT ... WHERE ... IN ...”
使用MySQLdb执行“SELECT ... WHERE ... IN ...”
尽管在mysql
命令行中类似的SQL语句能够正常工作,但我在Python中执行某些SQL时遇到了问题。表格的结构如下所示:
mysql> SELECT * FROM foo; +-------+-----+ | fooid | bar | +-------+-----+ | 1 | A | | 2 | B | | 3 | C | | 4 | D | +-------+-----+ 4 rows in set (0.00 sec)
我可以在mysql命令行中执行以下SQL查询,没有问题:
mysql> SELECT fooid FROM foo WHERE bar IN ('A','C'); SELECT fooid FROM foo WHERE bar IN ('A','C'); +-------+ | fooid | +-------+ | 1 | | 3 | +-------+ 2 rows in set (0.00 sec)
然而,当我尝试在Python中执行相同的查询时,返回的结果为空,而我期望得到2行的结果:
import MySQLdb import config connection=MySQLdb.connect( host=config.HOST,user=config.USER,passwd=config.PASS,db='test') cursor=connection.cursor() sql='SELECT fooid FROM foo WHERE bar IN %s' args=[['A','C']] cursor.execute(sql,args) data=cursor.fetchall() print(data) # ()
所以问题是:应该如何修改Python代码以选择那些bar
在('A','C')
中的fooid
?
顺便提一下,我注意到如果我交换bar
和fooid
的角色,我可以成功地使代码选择那些fooid
在(1,3)
中的bar
。我不明白为什么下面的查询可以正常工作,而上面的查询不行。
sql='SELECT bar FROM foo WHERE fooid IN %s' args=[[1,3]] cursor.execute(sql,args) data=cursor.fetchall() print(data) # (('A',), ('C',))
为了更加明确,这是foo
表格的创建方式:
mysql> DROP TABLE IF EXISTS foo; Query OK, 0 rows affected (0.00 sec) mysql> CREATE TABLE `foo` ( `fooid` int(11) NOT NULL AUTO_INCREMENT, `bar` varchar(10) NOT NULL, PRIMARY KEY (`fooid`)); Query OK, 0 rows affected (0.01 sec) mysql> INSERT into foo (bar) values ('A'),('B'),('C'),('D'); Query OK, 4 rows affected (0.00 sec) Records: 4 Duplicates: 0 Warnings: 0
编辑:当我使用mysqld -l /tmp/myquery.log
启用通用查询日志时,我看到:
mysqld, Version: 5.1.37-1ubuntu5.5-log ((Ubuntu)). started with: Tcp port: 3306 Unix socket: /var/run/mysqld/mysqld.sock Time Id Command Argument 110101 11:45:41 1 Connect unutbu@localhost on test 1 Query set autocommit=0 1 Query SELECT fooid FROM foo WHERE bar IN ("'A'", "'C'") 1 Query SELECT bar FROM foo WHERE fooid IN ('1', '3') 1 Quit
确实,看起来在'A'和'C'周围放置了过多的引号。
感谢@Amber的评论,我更好地理解了出了什么问题。MySQLdb将参数化的参数['A','C']
转换为("'A'","'C'")
。
是否有一种方法可以使用IN
SQL语法进行参数化查询?还是必须手动构建SQL字符串?