список python в sql-запросе в качестве параметра
у меня есть список python, скажем l
l = [1,5,8]
Я хочу написать SQL-запрос, чтобы получить данные для всех элементов списка, скажем
select name from students where id = |IN THE LIST l|
Как мне это сделать?
9 ответов:
ответы до сих пор были шаблоном значений в простую строку SQL. Это абсолютно нормально для целых чисел, но если мы хотим сделать это для строк, мы получаем проблему с побегом.
вот вариант с использованием параметризованного запроса, который будет работать для обоих:
placeholder= '?' # For SQLite. See DBAPI paramstyle. placeholders= ', '.join(placeholder for unused in l) query= 'SELECT name FROM students WHERE id IN (%s)' % placeholders cursor.execute(query, l)
SQL, который вы хотите, это
select name from studens where id in (1, 5, 8)
если вы хотите построить это из python, вы можете использовать
l = [1, 5, 8] sql_query = 'select name from studens where id in (' + ','.join(map(str, l)) + ')'
The карта функция преобразует список в список строк, которые могут быть склеены запятыми с помощью str.присоединяйтесь метод.
кроме того:
l = [1, 5, 8] sql_query = 'select name from studens where id in (' + ','.join((str(n) for n in l)) + ')'
если вы предпочитаете выражений генератор функции карте.
обновление: S. Lott упоминает в комментариях, что привязки Python SQLite не поддерживают последовательности. В этом случае вы можете захотеть
select name from studens where id = 1 or id = 5 or id = 8
создается с помощью
sql_query = 'select name from studens where ' + ' or '.join(('id = ' + str(n) for n in l))
строку.присоединяйтесь значения списка разделяются запятыми, и используйте оператор формате для формирования строки запроса.
myquery = "select name from studens where id in (%s)" % ",".join(map(str,mylist))
(спасибо, Блэр-Конрад)
мне нравится ответить bobince это:
placeholder= '?' # For SQLite. See DBAPI paramstyle. placeholders= ', '.join(placeholder for unused in l) query= 'SELECT name FROM students WHERE id IN (%s)' % placeholders cursor.execute(query, l)
но я заметил это:
placeholders= ', '.join(placeholder for unused in l)
можно заменить на:
placeholders= ', '.join(placeholder*len(l))
Я нахожу это более прямым, если менее умным и менее общим. Здесь
l
требуется иметь длину (т. е. ссылаться на объект, который определяет__len__
метод), который не должен быть проблемой. Но заполнитель также должен быть одним символом. Для поддержки многосимвольного заполнителя используйте:placeholders= ', '.join([placeholder]*len(l))
решение для @umounted ответа, потому что это сломалось с одноэлементным кортежем, так как (1,) не является допустимым SQL.:
>>> random_ids = [1234,123,54,56,57,58,78,91] >>> cursor.execute("create table test (id)") >>> for item in random_ids: cursor.execute("insert into test values (%d)" % item) >>> sublist = [56,57,58] >>> cursor.execute("select id from test where id in %s" % str(tuple(sublist)).replace(',)',')')) >>> a = cursor.fetchall() >>> a [(56,), (57,), (58,)]
другое решение для строки sql:
cursor.execute("select id from test where id in (%s)" % ('"'+'", "'.join(l)+'"'))
например, если вы хотите sql-запрос:
select name from studens where id in (1, 5, 8)
о:
my_list = [1, 5, 8] cur.execute("select name from studens where id in %s" % repr(my_list).replace('[','(').replace(']',')') )
это использует подстановку параметров и заботится об одном случае списка значений:
l = [1,5,8] get_operator = lambda x: '=' if len(x) == 1 else 'IN' get_value = lambda x: int(x[0]) if len(x) == 1 else x query = 'SELECT * FROM table where id ' + get_operator(l) + ' %s' cursor.execute(query, (get_value(l),))