python agrega “E” a la cadena

Esta cadena:

"CREATE USER %s PASSWORD %s", (user, pw) 

siempre se expande a:

 CREATE USER E'someuser' PASSWORD E'somepassword' 

puede alguien decirme por que?

Editar: La cadena expandida de arriba es la cadena que mi base de datos me da en el mensaje de error. Estoy usando psycopg2 para acceder a mi base de datos de postgres. El código real se ve así:

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

No solo la E, sino que las citas parecen provenir de cualquier tipo de usuario y pw. % s simplemente hace lo que hace str (), que puede recurrir a repr (), los cuales tienen los métodos correspondientes __str__ y __repr__ . Además, ese no es el código que genera tu resultado (asumí que había un%, pero ahora solo veo una coma). Por favor, amplíe su pregunta con el código real, los tipos y los valores.

Anexo: Teniendo en cuenta que se parece a SQL, me atrevería a suponer que está viendo constantes de cadenas de escape , probablemente generadas correctamente por su módulo de interfaz de base de datos o biblioteca.

Para pasar identificadores a postgresql a través de psycopg, use AsIs del módulo de 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' 

Eso funciona también para pasar condiciones a cláusulas como 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' 

Como la edición del OP revela que está usando PostgreSQL, los documentos para ello son relevantes, y dicen:

PostgreSQL también acepta constantes de cadena de “escape”, que son una extensión del estándar SQL. Una constante de cadena de escape se especifica escribiendo la letra E (mayúscula o minúscula) justo antes de la comilla simple de apertura, por ejemplo, E’foo ‘.

En otras palabras, psycopg está generando correctamente constantes de cadena de escape para sus cadenas (de modo que, como dicen los documentos, también:

Dentro de una cadena de escape, un carácter de barra invertida () comienza una secuencia de escape de barra invertida tipo C, en la que la combinación de barra diagonal inversa y los siguientes caracteres representa un valor de byte especial.

(que a su vez son también las convenciones de escape de los literales de cadenas de Python no crudos).

El error del OP claramente no tiene nada que ver con eso, y, además de la excelente idea de estudiar los excelentes documentos de PostgreSQL, no debe preocuparse por la forma E'...' en este caso ;-).

Antes de intentar algo como:

 statement = "CREATE USER %s PASSWORD %s" % (user, pw) 

Asegúrese de leer: http://www.initd.org/psycopg/docs/usage.html

Básicamente, el problema es que si está aceptando la entrada del usuario (supongo que para que alguien esté ingresando en el usuario & pw) es probable que se quede abierto a la inyección de SQL.

Como dice 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. 

Como se ha identificado, Postgres (o Psycopg2) no parece proporcionar una buena respuesta para escapar de los identificadores. En mi opinión, la mejor manera de resolver esto es proporcionar un método de filtro de “lista blanca”.

es decir: identifique qué caracteres están permitidos en un ‘usuario’ y un ‘pw’. (tal vez A-Za-z0-9_). Tenga cuidado de no incluir caracteres de escape (‘o;, etc.) o, si lo hace, de estos valores.