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()
4 ответа
Похоже, что не только E, но и кавычки приходят от любого типа user и pw. %s просто делает то, что делает str(), что может привести к repr(), оба из которых имеют соответствующие методы __str__
а также __repr__
, Кроме того, это не тот код, который генерирует ваш результат (я предположил, что был%, но теперь вижу только запятую). Пожалуйста, дополните ваш вопрос фактическим кодом, типами и значениями.
Приложение: Учитывая, что это похоже на SQL, я бы рискнул предположить, что вы видите константы escape-строки, которые, вероятно, правильно сгенерированы вашим интерфейсным модулем базы данных или библиотекой.
Для передачи идентификаторов в 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'
Как показывает редактирование OP, он использует PostgreSQL, документы для него актуальны, и они говорят:
PostgreSQL также принимает строковые константы escape, которые являются расширением стандарта SQL. Константа escape-строки указывается путем написания буквы E (в верхнем или нижнем регистре) непосредственно перед открывающей одинарной кавычкой, например, E'foo.
Другими словами, psycopg правильно генерирует константы escape-строки для ваших строк (так что, как говорят в документации:
Внутри escape-строки символ обратной косой черты () начинает C-подобную escape-последовательность обратной косой черты, в которой комбинация обратной косой черты и следующих символов представляет специальное байтовое значение.
(что, как это бывает, также является условным обозначением escape-строковых литералов Python).
Ошибка ОП явно не имеет к этому никакого отношения, и, кроме отличной идеи изучения превосходных документов PostgreSQL, ему не стоит об этом беспокоиться E'...'
форма в этом случае;-).
Прежде чем пытаться что-то вроде:
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), по-видимому, не дают хорошего ответа на экранирующие идентификаторы. На мой взгляд, лучший способ решить эту проблему - предоставить метод фильтрации "белого списка".
То есть: определить, какие символы разрешены в "пользователя" и "PW". (возможно A-Za-z0-9_). Будьте осторожны, чтобы не включать escape-символы ('или; и т. Д.) Или, если вы это делаете, избегать этих значений.