2017-05-09 111 views
1

我有一個數據庫名字的字典。我取了個名字從字典如何從Python的SQL查詢字符串中刪除引號?

database_name = database_dict[i] 

可以說對數據庫名稱的值是「富」

使用Psycopg2我執行語句:

cur.execute("INSERT INTO %s VALUES(...);", database_name) 

我會在foo的語法錯誤,因爲它應該是「INSERT INTO foo VALUES」而不是「INSERT INTO'foo'VALUES」

任何建議如何傳遞一個字符串值的名稱的表和刪除單引號?我應該在數據庫字典值中放置一個轉義字符嗎?

編輯:更接近於是在這裏:How do I remove single quotes from a table in postgresql?

,但我無法得到它使用拆卸工作。它在remove語句中的單引號中給出了語法錯誤。

+1

標識符(如表和列名稱)在標準SQL(和PostgreSQL)中使用雙引號,因此您需要使用特定於標識符的引用方法。 AFAIK這意味着['quote_ident'](http://initd.org/psycopg/docs/extensions.html#psycopg2.extensions.quote_ident)和字符串連接,但我不知道足夠的Python或Psycopg2以確保最好/正確的方法。 –

+0

是'database_dict [i]'''foo''或'foo'的值嗎?報價來自哪裏? – Schwern

回答

3

SQL查詢,如表和字段名的結構部件如你在cursor.execute(query, params)第二個參數試圖不能進行參數設置。只有數字/文字數據值可以參數化。

考慮插值數據庫名稱變量到SQL查詢字符串,但使用psycopg2的sqlIdentifier()str.format安全地這樣做:

from psycopg2 import sql 
... 

cur.execute(sql.SQL('INSERT INTO {} VALUES(...)').format(sql.Identifier(database_name))) 

有效parameterizaiton你的情況將綁定傳入的數據值在VALUES(...)附加查詢如VALUES(%s, %s, %s)。或者在其他查詢:

"SELECT %s AS NewColumn..." 

"...WHERE fieldname = %s OR otherfield IN (%s, %s, %s)" 

"...HAVING Max(NumColumn) >= %s" 
+0

直接插值而不轉義'database_name'會引發SQL注入攻擊。 – Schwern

+0

通過使用.format,我能夠克服這個限制。謝謝@Parfait –

+0

由於在我的應用程序中沒有填寫字段,所以沒有SQL注入的風險。 –

0

如果其實database_name"'foo'"

要刪除單引號:

database_name = database_name.replace("'", "") 
+0

這是不正確的。我的價值是一個字符串。我不能在沒有單引號的情況下將字符串插入到SQL語句中。你的建議沒有奏效。 –

+0

正確,%s將它用單引號括起來,但是我不能在SQL語句中引用引號。 –

0

注:我沒有使用psycopg2,這是基於什麼我從類似的數據庫庫知道。

表名是一個標識符,他們得到引述逃到不同於值。我相信你應該使用psycopg2.extensions.quote_ident(str, scope)來引用和逃避它。我相信它使用PostgreSQL函數PQescapeIdentifier()

PQescapeIdentifier轉義字符串以用作SQL標識符,例如表,列或函數名稱。如果用戶提供的標識符可能包含特殊字符,否則SQL解析器不會將其解釋爲標識符的一部分,或者標識符可能包含應保留大小寫的大寫字符時,這很有用。

然後,它會被引用,並逃脫了,可以放心地加入到使用正常的字符串操作SQL字符串,而不用擔心一SQL injection attack,或使用AsIs(quote_ident(database_name))作爲值.execute

相關問題