Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python添加了;";串_Python_Postgresql_Psycopg - Fatal编程技术网

python添加了;";串

python添加了;";串,python,postgresql,psycopg,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

此字符串:

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

不仅是E,而且引号似乎来自用户和pw的任何类型s只做str()所做的事情,这可能会返回到repr(),这两个函数都有相应的方法
\uu str\uuuuuuuu
\uuuuu repr\uuuu
。另外,这不是生成结果的代码(我假设有%,但现在只看到一个逗号)。请用实际代码、类型和值展开您的问题


附录:考虑到它看起来像SQL,我冒昧地猜测一下您看到的,可能是由您的数据库接口模块或库正确生成的。

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

PostgreSQL也接受“转义” 字符串常量,它是 SQL标准的扩展。一 转义字符串常量由指定 写字母E(大写或小写) 案例)就在首张单曲之前 引用,例如e'foo'

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

在转义字符串中,使用反斜杠 字符()以类C开头 反斜杠转义序列,其中 反斜杠和斜杠的组合 以下字符表示一个或多个 特殊字节值

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


OP的错误显然与此无关,而且,除了学习PostgreSQL优秀文档的绝妙想法外,他不应该担心本例中的
E'…
表单;-)。

在尝试以下操作之前:

statement = "CREATE USER %s PASSWORD %s" % (user, pw)
请确保阅读:

基本上,问题是,如果您接受用户输入(我假设有人正在输入用户&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)。请注意不要包含转义字符('or;,等等),如果包含,请转义这些值

要通过psycopg将标识符传递给postgresql,请使用
extensions
模块中的
AsIs

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'
这也适用于将条件传递给子句,如
orderby

cur.mogrify(
    'select * from t order by %s', (AsIs('some_column, another column desc'),)
    )
'select * from t order by some_column, another column desc'

你能给出包含用户和pw声明的完整代码吗?这一定是由
用户
pw
类型的
\uuu str\uuuu
函数的行为引起的。字符串文本后是逗号吗?如果是这样的话,表达式就是一个嵌套的元组,任何东西都不会被扩展。请出示真实代码。你是对的。我使用的是Psycopg2,这是数据库作为错误返回给我的字符串。我现在要把实际的代码放在问题中。问题似乎是%s用于数据字段,而中的用户名似乎是一个标识符-因此字符串文字在那里不起作用。Psycopg2似乎没有任何验证或引用此类标识符的函数。@Yann,讨论转移到,因为…我只是自己读的。所以字符串是正确的,但是为什么我的postgres服务器在E上用一个语法错误将它返回给我?@Kai,也许你使用的是过时的PgSQL版本?或者@Yann对另一个答案的评论是正确的,您需要一个标识符,而不是一个带引号的字符串,在
CREATE USER
(在这种情况下,您必须在
execute
之前通过字符串操作插入它,以避免转义——当然,要确保对SQL注入攻击进行彻底检查!!!-).看起来Yann的评论是对的。我不喜欢这样,但目前我不需要在这些语句中处理用户生成的值。因此,我将只使用标准的python字符串操作。不过,我还是不喜欢;)太糟糕了,它无法实现查询参数化:
>>cursor.mogrify('CREATE USER%s PASSWORD%s',(AsIs('someuser'),AsIs('somepassword;drop table users;'))
'CREATE USER someuser PASSWORD somepassword;删除表用户;'应该使用类似以下内容进行验证:
'input\u table'.replace('''u','').isalnum()
。(注意,未经测试。)@MichałPawłowski:是的,
AsIs
不应用于用户输入的数据。使用任何未经彻底测试的解决方案(如您的解决方案)都会带来灾难。Postgres具有引用标识符的
quote_ident()
函数