2013-04-27 46 views
1

我有一個查詢字符串,它運行在循環的一側,列表查詢中的每個項目都被執行。該列表包含字符串,我使用python字符串格式技術將迭代過程中的查詢替換爲列表中相應的字符串。Python:從MySQL中退出單引號查詢

我曾與從列表中字符串沿着unicoded查詢:這裏是我的unicoded查詢:

query = ur'''SELECT something FROM some_table WHERE some_name LIKE "{this_name}%"''' 

執行我編碼查詢字符串來utf-8

  try: 
       formatted_query = query.format(this_name=list_name) 
       #encode the query 
       encoded_q = formatted_query.encode('utf-8') 
       # execute the query 
       self.dbCursor.execute(encoded_q) 
       row = self.dbCursor.fetchone() 
      except Exception, e: 
       traceback.print_exc() 

但問題之前有時我會遇到單引號示例的列表中的字符串:foo's。我已經使用utf-8進行了unicoded,我認爲這樣做不必擔心這種情況。但是我得到了sql錯誤,因爲MySQL沒有跳過單引號。

我的下一個嘗試是代替單引號:

format_string = u"foo's".replace(u"'",u"\'") 

但是,這也不能工作。我還看到this question的答案正在使用mysqldb庫,這是我不知道的內置函數,所以我尋求來自stackoverflow社區的幫助來解決這個問題。

我更改代碼,以反映在回答提出的解決方案,但結果是一樣的:這裏是改變:

錯誤:

args = [u"{this_name}%".format(this_name=format_name)] 
self.dbCursor.execute(query.encode('utf-8'), args) 

#ERROR在這行拋出:

UnicodeEncodeError: 'latin-1' codec can't encode character u'\u014d' in position 4: ordinal not in range(256) 

這是字符串,錯誤抱怨,我檢查了該字符串的類型是一個單字符串。

this_name= Sentōkisei type= <type 'unicode'> 
+0

如果您刪除原始標誌,會發生什麼情況? – 2013-04-27 15:25:10

+0

真的不明白你的意思 – 2013-04-27 15:31:23

回答

4

如果您使用兩個參數調用dbCursor.execute,您的數據庫適配器將爲您引用參數。見DB-API specification的細節:

query = u'''SELECT something FROM some_table WHERE some_name LIKE %s''' 
args = [u"{this_name}%".format(this_name=list_name)] 
self.dbCursor.execute(query, args) 

%squeryparameter marker。它將被替換爲args中給出的引用參數。要使用的正確參數標記取決於您的數據庫適配器。例如,MySQLdb使用%s,而oursqlsqlite3使用?

使用參數化SQL是推薦的方法。你真的不應該自己引用這些論點。


關於錯誤,您發佈的

this_name= Sentōkisei type= <type 'unicode'> 

我要承擔這意味着format_name是unicode。因此,

args = [u"{this_name}%".format(this_name=format_name)] 

會讓args包含一個統一的列表。

現在我們到達這是引發錯誤行:

self.dbCursor.execute(query.encode('utf-8'), args) 

query已經unicode。如果您編碼該unicode,則它將變爲str。所以query.encode('utf-8')str,但是argsunicode的列表。我不知道爲什麼你想編碼query,但你的數據庫適配器應該能夠採取兩個unicode參數。因此,嘗試

self.dbCursor.execute(query, args) 

現在,在重新閱讀您的意見,看來你已經嘗試這樣做,它也提出了同樣的錯誤:

UnicodeEncodeError: 'latin-1' codec can't encode character u'\u014d' in position 75: ordinal not in range(256) 

我不知道爲什麼DB適配器嘗試使用latin-1對代碼進行編碼,而不是utf-8。最好的解決方案是追蹤這個選擇來自哪裏latin-1

哈克解決方法是嘗試自己編碼字符串:

query = u'''SELECT something FROM some_table WHERE some_name LIKE %s'''.encode('utf-8') 
args = [u"{this_name}%".format(this_name=list_name).encode('utf-8')] 
self.dbCursor.execute(query, args) 

但我要強調我真的不認爲這是最好的方式,也不應該這個是必要的。

+0

所以,我不需要這樣做:'encoded_q = formatted_query.encode('utf-8')'? – 2013-04-27 16:31:34

+1

關於Unicode,我認爲''{this_name}%「'需要用'u」{this_name}%「'替換。 – 2013-04-27 16:54:02

+0

我認爲是因爲使用建議的解決方案,我得到了下面的結果:'UnicodeEncodeError:'ascii'編解碼器無法在位置1編碼字符u'\ xf3':序號不在範圍內(128) 因爲我必須處理字符串像這樣Hójtype = 但是我檢查了這個類型,並且在此之前我已經統一了它。 – 2013-04-27 16:56:37