У меня возникла проблема с выполнением некоторого SQL из Python, несмотря на то, что аналогичный SQL работает нормально из командной строки mysql.
Таблица выглядит так:
mysql> SELECT * FROM foo;
+-------+-----+
| fooid | bar |
+-------+-----+
|     1 | A   | 
|     2 | B   | 
|     3 | C   | 
|     4 | D   | 
+-------+-----+
4 rows in set (0.00 sec)
Я могу выполнить следующий SQL-запрос из командной строки mysql без проблем:
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, чтобы выбрать те fooid, где bar находится в ('A','C')?
Кстати, я заметил, что если я переключу роли bar и fooid, я могу получить код, чтобы выбрать те bar, где fooid находится в (1,3) успешно. Я не понимаю, почему один такой запрос (ниже) работает, а другой (выше) не работает.
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   [email protected] 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?