15

这个字符串:

"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

4 回答 4

17

通过模块中的 psycopg 使用AsIs将标识符传递给 postgresqlextensions

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'
于 2012-12-15T10:47:28.597 回答
10

正如 OP 的编辑显示他正在使用 PostgreSQL,它的文档是相关的,他们说:

PostgreSQL 还接受“转义”字符串常量,这是对 SQL 标准的扩展。转义字符串常量通过在开始单引号之前写入字母 E(大写或小写)来指定,例如 E'foo'。

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

在转义字符串中,反斜杠字符 () 开始一个类似 C 的反斜杠转义序列,其中反斜杠和后续字符的组合表示一个特殊的字节值。

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

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

于 2010-08-01T15:39:11.777 回答
8

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

附录:考虑到它看起来像 SQL,我猜测您看到的是转义字符串常量,可能是由您的数据库接口模块或库正确生成的。

于 2010-08-01T13:48:29.263 回答
2

在尝试以下操作之前:

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

请确保您阅读: http: //www.initd.org/psycopg/docs/usage.html

基本上问题是,如果您接受用户输入(我假设有人输入用户和密码),您可能会让自己对 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)似乎没有为转义标识符提供一个好的答案。在我看来,解决此问题的最佳方法是提供“白名单”过滤方法。

即:确定“用户”和“密码”中允许使用哪些字符。(也许是 A-Za-z0-9_)。请注意不要包含转义字符(' 或 ; 等),或者如果包含转义字符,请转义这些值。

于 2011-06-01T16:22:34.467 回答