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-символы ('или; и т. Д.) Или, если вы это делаете, избегать этих значений.

Другие вопросы по тегам