Подтвердить что ты не робот

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()
4b9b3361

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