python将“E”添加到字符串

时间:2010-08-01 13:40:16

标签: python postgresql psycopg

此字符串:

"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 个答案:

答案 0 :(得分:17)

要通过psycopg将标识符传递给postgresql,请使用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'

答案 1 :(得分:10)

由于OP的编辑显示他正在使用PostgreSQL,the docs因为它是相关的,他们说:

  

PostgreSQL也接受“逃避”   字符串常量,是一个   SQL标准的扩展。一个   转义字符串常量由。指定   写字母E(上面或下面   案例)就在开幕单之前   引用,例如E'foo”。

换句话说,psycopg正确地为你的字符串生成转义字符串常量(因此,正如文档所说:

  

在转义字符串中,反斜杠   character()开始像C一样   反斜杠转义序列,其中   反斜杠和。的组合   以下字符代表a   特殊字节值。

(碰巧也是非原始Python字符串文字的转义约定)。

OP的错误显然与此无关,除了研究PostgreSQL优秀文档的优秀想法之外,他不应该担心这种情况下的E'...'形式; - )。

答案 2 :(得分:8)

不仅E而且引号似乎来自用户和pw所具有的任何类型。 %s只执行str()所做的事情,这可能会回退到repr(),两者都有相应的方法__str____repr__。此外,这不是生成结果的代码(我假设有一个%,但现在只看到一个逗号)。请使用实际代码,类型和值扩展您的问题。

附录:考虑到它看起来像SQL,我猜测你看到escape string constants,可能是你的数据库接口模块或库正确生成的。{/ p>

答案 3 :(得分:2)

在尝试之前:

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_)。请注意,不要包含转义字符('或;等等),或者如果你这样做,则要转义这些值。