2009-09-23 209 views
30

使psycopg2將參數化查詢傳遞給PostgreSQL的最佳方式是什麼?我不想編寫自己的escpaing機制或適配器,並且psycopg2源代碼和示例很難在Web瀏覽器中閱讀。使用psycopg2/Python DB-API和PostgreSQL的參數化查詢

如果我需要切換到像PyGreSQL或另一個python pg適配器,這對我來說沒問題。我只是想簡單的參數化。

+0

什麼樣的你想要參數化嗎?僞代碼樣本將很有用。 – whatnick 2009-09-23 15:53:58

+0

Sidenote,你可能想看看SQLAlchemy,在某些方面入門的成本可能會稍微高一些,但它確實是一個非常好的ORM。 – 2009-11-09 18:55:38

+0

爲了將來的參考,答案在文檔的第一頁:http://initd.org/psycopg/docs/usage.html – piro 2011-05-16 16:07:16

回答

60

psycopg2遵循DB-API 2.0的規則(設置在PEP-249中)。這意味着你可以從你的cursor對象中調用execute方法,並使用pyformat綁定樣式,它會爲你逃脫。例如,下面的應該是安全的(工作):

cursor.execute("SELECT * FROM student WHERE last_name = %(lname)s", 
       {"lname": "Robert'); DROP TABLE students;--"}) 
+42

哈哈,我剛剛得到了......小鮑比桌子! http://xkcd.com/327/ – adam 2010-07-13 14:25:08

+1

所以上面的代碼。丟下桌子還是不? – mascot6699 2016-03-26 19:40:07

+1

@ mascot6699它沒有,因爲查詢是參數化的。 – 2017-06-02 18:58:05

13

這裏有幾個例子,你可能會發現有用

cursor.execute('SELECT * from table where id = %(some_id)d', {'some_id': 1234}) 

或者,你可以動態地構建基於字段名,值的字典查詢:

fields = ', '.join(my_dict.keys()) 
values = ', '.join(['%%(%s)s' % x for x in my_dict]) 
query = 'INSERT INTO some_table (%s) VALUES (%s)' % (fields, values) 
cursor.execute(query, my_dict) 

注:該字段必須是在您的代碼中定義,不是用戶輸入,否則您將容易受到SQL注入的影響。

+5

那麼除非你知道你在做什麼,你應該只是concat輸入到SQL查詢中,因爲它是一個SQL注入。 – 2013-01-25 18:45:40

+3

downvoted由於建議,讓你打開SQL注入 – 2014-12-23 05:04:57

+2

@RandySyring這隻對SQL注入開放,如果密鑰沒有很好定義和正確的標識符。值仍然正確參數化。 – cpburnz 2015-04-07 14:17:33

10

從psycopg文檔

http://initd.org/psycopg/docs/usage.html

警告決不,決不,決不使用Python字符串串聯(+)或字符串參數插值(%)將變量傳遞給SQL查詢字符串。甚至沒有槍支。

傳遞變量在SQL命令的正確的方法是使用execute()方法的第二個參數:

SQL = "INSERT INTO authors (name) VALUES (%s);" # Note: no quotes

data = ("O'Reilly",)

cur.execute(SQL, data) # Note: no % operator