psycopg2 странное поведение
from django.db import connection
q = 'some value'
sql1 = 'SELECT * FROM table WHERE field LIKE %%%s%%' % q
sql2 = 'SELECT * FROM table WHERE field LIKE %%'+ q +'%%'
cursor = connection.cursor()
cursor.execute( sql1 ) #why exception: IndexError: tuple index out of range ?
cursor.execute( sql2 ) #works ok
3 ответа
Вы должны правильно указать свои аргументы SQL.
Под правильным цитированием я подразумеваю использование возможности цитирования, предоставляемой DBAPI, а не добавление 'вокруг вашей строки, что бесполезно.
Правильный код:
q = "%"+q+"%"
cursor.execute( 'SELECT * FROM table WHERE field LIKE %s', (q,) )
Действительно правильный код:
q = "%"+q.replace("%","%%")+"%"
cursor.execute( 'SELECT * FROM table WHERE field LIKE %s', (q,) )
Предположим, что q = "a'bc". Сначала перепишите это как "% a'bc%". Затем используйте его в качестве обычного строкового аргумента. psycopg перепишет его как "%a\" bc% ", как и должно быть.
Если q может содержать "%", и вы хотите найти его, используйте второй.
Использование прямой манипуляции со строками почти наверняка приведет к неправильному SQL, который уязвим для атак SQL-инъекций ( см. Комментарий psycopg2 по этому вопросу).
Я думаю, что вы хотите сделать, это попытаться выполнить LIKE '%some value%' в django, верно?:
from django.db import connection
q = '%some value%'
cur = connection.cursor()
cur.execute("SELECT * FROM table WHERE field LIKE %(my_like)s", {'my_like': q})
Начиная с psycopg2 2.4.1, SQL, который выполняется на сервере:
SELECT * FROM table WHERE field LIKE '%some value%'
Вы должны правильно ЗАКАЗАТЬ вашу команду SQL:
sql1 = "SELECT * FROM table WHERE field LIKE '%%%s%%'" % q
sql2 = "SELECT * FROM table WHERE field LIKE '%"+ q +"%'"
И, цитируя правильно, я имею в виду использование одинарных кавычек с LIKE
выражения.