Форматы строк Python с Подстановочными знаками SQL и тому подобное

Мне трудно получить некоторый sql в python, чтобы правильно пройти через MySQLdb. Меня убивает форматирование строк pythons.

мой оператор sql использует ключевое слово LIKE с подстановочными знаками. Я пробовал несколько разных вещей в Python. Проблема в том, что как только я получаю один из них, есть строка кода в MySQLdb, которая рыгает в строковом формате.

Попытка 1:

"выберите тег.userId, count (пользователь.id) как totalRows от пользователя ВНУТРЕННЕЕ СОЕДИНЕНИЕ тег на пользователя.id = тег.userId где пользователь.имя пользователя, например "%%s% "" % (query)

Это не пойдет. Я получаю ошибку значения:

ValueError: неподдерживаемый символ формата "' (0x27) при индексе 128

Попытка 2:

"выберите тег.userId, count (пользователь.id) как totalRows от внутреннего соединения пользователя тег на пользователя.id = тег.userId где пользователь.имя пользователя, например " %%s%"" % (запрос)

Я получаю тот же результат с 1 попытки.

Попытка 3:

like = "LIKE' % "+ str (query) + " % ""totalq =" выберите тег.идентификатор пользователя, count (пользователь.id) как totalRows от тега внутреннего соединения пользователя на пользователе.id = метка.userId где пользователь.имя пользователя " + like

это правильно создает переменную totalq, но теперь, когда я иду запускать запрос, я получаю ошибки от MySQLdb:

файл "build/bdist.macosx-10.6-universal/egg/MySQLdb/cursors.py", линия 158, В выполнить query = запрос % db.literal (args) TypeError: недостаточно аргументы для строки формата

попытка 4:

like = "LIKE' % "+ str (query) + " % '"totalq =" выберите тег.идентификатор пользователя, count (пользователь.id) как totalRows от тега внутреннего соединения пользователя на пользователе.id = метка.userId где пользователь.имя пользователя " + like

Это тот же результат, что и попытка 3.

все это кажется очень странным. Как я могу использовать подстановочные знаки в инструкциях sql с в Python?

4 ответов


речь идет не о форматировании строк, но проблема в том, как запросы должны выполняться в соответствии с требованиями к операциям БД в Python (PEP 249)

попробуйте что-то вроде этого:

sql = "SELECT column FROM table WHERE col1=%s AND col2=%s" 
params = (col1_value, col2_value)
cursor.execute(sql, params)

вот несколько примеров для psycog2 где у вас есть некоторые объяснения, которые также должны быть действительны для mysql (mysqldb также следует pep249 DBA api guidance 2.0:вот примеры для mysqldb)


все эти запросы, по-видимому, уязвимы для атак SQL-инъекций.

попробуйте что-то вроде этого:

curs.execute("""SELECT tag.userId, count(user.id) as totalRows 
                  FROM user 
            INNER JOIN tag ON user.id = tag.userId 
                 WHERE user.username LIKE %s""", ('%' + query + '%',))

где два аргумента передаются в execute().


чтобы избежать амперсандов в выражениях форматирования строк Python, удвоьте амперсанд:

'%%%s%%' % search_string

Edit: но я определенно согласен с другим ответом. Прямая подстановка строк в SQL-запросах почти всегда является плохой идеей.


у меня есть решение вашей проблемы :

вы не можете использовать :

"SELECT tag.userId, count(user.id) as totalRows FROM user INNER JOIN tag ON user.id = tag.userId WHERE user.username LIKE '%%s%'" % (query)

вы можете изменить его с помощью шаблона строки, например :

import MySQLdb
import string # string module
.......
value = {'user':'your value'}
sql_template = string.Template("""
SELECT tag.userId, count(user.id) as totalRows FROM user INNER JOIN
tag ON user.id = tag.userId WHERE user.username LIKE '%$user%'
""")

sql = sql_template.substitute(value)

try:
    cursor.execute(sql)
    ...........
except:
    ...........
finally :
   db.close()