Python добавляет "E" к строке - PullRequest
       35

Python добавляет "E" к строке

15 голосов
/ 01 августа 2010

Эта строка:

"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 ]

17 голосов
/ 15 декабря 2012

Для передачи идентификаторов в 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'
10 голосов
/ 01 августа 2010

Поскольку редактирование ОП показывает, что он использует PostgreSQL, документы для него актуальны, и они говорят:

PostgreSQL также принимает "escape" строковые константы, которые являются расширение к стандарту SQL. константа escape-строки определяется как написание письма E (верхний или нижний случай) как раз перед открытием сингла цитата, например E'foo.

Другими словами, psycopg правильно генерирует константы escape-строки для ваших строк (так что, как говорят в документации:

Внутри escape-строки, обратной косой черты персонаж () начинает C-подобный escape-последовательность обратной косой черты, в которой сочетание обратной косой черты и следующий символ (ы) представляет специальное значение байта.

(что также является условным обозначением escape-строковых литералов Python).

Ошибка ОП явно не имеет к этому никакого отношения, и, кроме отличной идеи изучения превосходных документов PostgreSQL, ему не следует беспокоиться об этой форме E'...' в этом случае; -).

8 голосов
/ 01 августа 2010

Похоже, что не только E, но и кавычки получены от пользователей любого типа и pw. % s просто делает то, что делает str (), что может привести к repr (), оба из которых имеют соответствующие методы __str__ и __repr__. Кроме того, это не тот код, который генерирует ваш результат (я предположил, что был%, но теперь вижу только запятую). Пожалуйста, дополните ваш вопрос фактическим кодом, типами и значениями.

Приложение: Учитывая, что это похоже на SQL, я рискну предположить, что вы видите экранирующие строковые константы , вероятно, правильно сгенерированные вашим модулем интерфейса базы данных или библиотекой.

2 голосов
/ 01 июня 2011

Прежде чем пытаться что-то вроде:

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), похоже, недать хороший ответ на экранирование идентификаторов.На мой взгляд, лучший способ решить эту проблему - предоставить метод фильтрации «белого списка».

, то есть: определить, какие символы разрешены в «user» и «pw».(возможно A-Za-z0-9_).Будьте осторожны, чтобы не включать escape-символы ('или; и т. Д.) Или, если вы это делаете, избегать этих значений.

...