I had a problem running some SQL from Python, even though a similar SQL works fine from the mysql command line.
The table looks like this:
mysql> SELECT * FROM foo; +-------+-----+ | fooid | bar | +-------+-----+ | 1 | A | | 2 | B | | 3 | C | | 4 | D | +-------+-----+ 4 rows in set (0.00 sec)
I can execute the following SQL query from mysql command line without any problems:
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)
However, when I try to do the same from Python, I don't get the lines, while I was expecting 2 lines:
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)
So the question is: how to change python code to select those fooid where bar is in ('A','C') ?
By the way, I noticed that if I switch the roles of bar and fooid , I can get the code to select those bar where fooid is in (1,3) successfully. I do not understand why one such request (below) works, and another (above) does not work.
sql='SELECT bar FROM foo WHERE fooid IN %s' args=[[1,3]] cursor.execute(sql,args) data=cursor.fetchall() print(data) # (('A',), ('C',))
And to be absolutely clear, here is how the foo table was created:
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
Change When I turn on the general query log with mysqld -l /tmp/myquery.log I see
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
Indeed, it seems that too many quotes are placed around A and C
Thanks to @Amber's comment, I better understand what is going wrong. MySQLdb converts the parameterized argument ['A','C'] to ("'A'","'C'") .
Is there a way to make a parameterized query using IN SQL syntax? Or do you need to manually build an SQL string?