我在Python中执行一些SQL时遇到了问题,尽管类似的SQL在mysql
命令行中运行得很好。
表格如下所示:
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字符串?
https://stackoverflow.com/questions/4574609
复制相似问题