Python добавляет строку "E" в строку
Эта строка:
"CREATE USER %s PASSWORD %s", (user, pw)
всегда расширяется до:
CREATE USER E'someuser' PASSWORD E'somepassword'
Может ли кто-нибудь сказать мне, почему?
Изменить:
Расширенная строка выше - это строка, в которой моя база данных возвращает мне сообщение об ошибке. Я использую psycopg2 для доступа к моей базе данных postgres. Настоящий код выглядит следующим образом:
conn=psycopg2.connect(user=adminuser, password=adminpass, host=host)
cur = conn.cursor()
#user and pw are simple standard python strings the function gets as parameter
cur.execute("CREATE USER %s PASSWORD %s", (user, pw))
conn.commit()
Ответы
Ответ 1
Не только E, но и кавычки появляются из любого типа пользователя и pw. % s просто делает то, что делает str(), которое может вернуться к repr(), оба из которых имеют соответствующие методы __str__
и __repr__
. Кроме того, это не код, который генерирует ваш результат (я предположил, что есть%, но теперь вижу только запятую). Пожалуйста, разверните свой вопрос с фактическим кодом, типами и значениями.
Добавление. Учитывая, что он похож на SQL, я бы предположил, что вы видите escape-константы строки, которые, вероятно, будут правильно сгенерированы модулем интерфейса базы данных или библиотека.
Ответ 2
Чтобы передать идентификаторы postgresql через psycopg, используйте AsIs
из модуля extensions
from psycopg2.extensions import AsIs
import psycopg2
connection = psycopg2.connect(database='db', user='user')
cur = connection.cursor()
cur.mogrify(
'CREATE USER %s PASSWORD %s', (AsIs('someuser'), AsIs('somepassword'))
)
'CREATE USER someuser PASSWORD somepassword'
Это также работает для передачи условий в выражения, такие как order by
:
cur.mogrify(
'select * from t order by %s', (AsIs('some_column, another column desc'),)
)
'select * from t order by some_column, another column desc'
Ответ 3
Поскольку в редакторе OP показано, что он использует PostgreSQL, документы для него актуальны, и они говорят:
PostgreSQL также принимает "escape" Строковые константы, которые являются расширение стандарта SQL. константа escape-строки определяется написав букву E (верхний или нижний случай) перед первым синглом цитата, например. E'foo".
Другими словами, psycopg корректно генерирует escape-строки для ваших строк (так что, как говорят документы,
В escape-строке обратная косая черта character() начинает C-like обратная косая черта, в которой комбинация обратной косой черты и следующий символ (символы) представляет собой специальное значение байта.
(которые, как это бывает, также являются соглашениями об исключении нестандартных строковых литералов Python).
Ошибка OP явно не имеет к этому отношения, и, кроме отличной идеи изучения превосходных документов PostgreSQL, он не должен беспокоиться об этой форме E'...'
в этом случае; -).
Ответ 4
Прежде чем пытаться что-то вроде:
statement = "CREATE USER %s PASSWORD %s" % (user, pw)
Пожалуйста, убедитесь, что вы прочитали: http://www.initd.org/psycopg/docs/usage.html
В основном проблема заключается в том, что если вы принимаете ввод пользователя (я предполагаю, что кто-то вводит пользователя и pw), вы, вероятно, оставите себя открытым для SQL-инъекции.
Как утверждает PsyCopg2:
Warning Never, never, NEVER use Python string concatenation (+) or string parameters interpolation (%) to pass variables to a SQL query string. Not even at gunpoint.
Как было установлено, Postgres (или Psycopg2), похоже, не дает хорошего ответа на экранирование идентификаторов. На мой взгляд, лучший способ разрешить это - предоставить фильтр "белый список".
ie: Определите, какие символы разрешены в "пользователе" и "pw". (возможно, A-Za-z0-9_). Будьте осторожны, чтобы вы не включили escape-символы ('или; и т.д.), Или если вы это сделаете, вы избежите этих значений.