繁体   English   中英

为什么 psycopg2 cursor.execute() 和 SQL 查询参数会导致语法错误?

[英]Why does psycopg2 cursor.execute() with SQL query parameter cause syntax error?

在 Python 中的 psycopg2 中为 execute() 指定参数时,如下所示:

cursor.execute('SELECT * FROM %s', ("my_table", ))

我收到此错误:

psycopg2.ProgrammingError: syntax error at or near "'my_table'"
LINE 1: SELECT * FROM 'my_table'

我究竟做错了什么? 看起来 psycopg2 正在向查询中添加单引号,而这些单引号导致语法错误。

如果我不使用参数,它可以正常工作:

cursor.execute('SELECT * FROM my_table')

我相信这样的参数化语句应与一起使用,而不是与表名(或SQL关键字等)一起使用。 因此,您基本上没有运气。

但是,请不要担心,因为该机制旨在防止SQL注入,并且您通常在代码编写时就知道要访问哪个表,因此几乎没有人可能注入恶意代码。 只需将表写入字符串即可。

如果出于某些(可能是不正确的)原因,您将表名保留为参数形式,例如:

  1. 如果表名来自您的程序(例如,字典或类属性),请执行通常的字符串替换。
  2. 如果表名来自外部世界(请考虑“用户输入”):要么不这样做,要么完全信任用户并采用前面的方法1。

例如:

cursor.execute(
    'SELECT * FROM %s where %s = %s'
    % ("my_table", "colum_name", "%s"), #1
    ("'some;perverse'string;--drop table foobar")) #2

#1 :此时将第三个%s替换为另一个'%s',以允许psycopg2稍后进行处理#2 :这是将被psycopg2正确引用并代替第三个'%s'放置的字符串在原始字符串中

cur.execute(
    """
    SELECT * FROM %s;
    """,
    {"my_table",}
)
conn.commit()

这个问题有点晚了,但是 Psycopg2 中有一些功能通过SQL String Composition支持这个用例。 这种方法提供了一种“以方便和安全的方式动态生成 SQL”的方法。

在原始答案的用例中:

cursor.execute(
    sql.SQL("SELECT * FROM {}").format(
        sql.Identifier("my_table")))

使用 SQL 字符串组合比通过 Irfy 的回答中讨论的%字符串参数插值更安全。 正如psycopg2 文档中所述

警告 永远,永远,永远不要使用 Python 字符串连接 (+) 或字符串参数插值 (%) 将变量传递给 SQL 查询字符串。 甚至不是在枪口下。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM