簡體   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