2016-08-23 112 views
9

我需要從我的python腳本調用MySQL存儲過程。作爲參數之一,我傳遞了一個unicode字符串(俄語),但我得到一個錯誤;Python與MySql unicode問題

UnicodeEncodeError: 'latin-1' codec can't encode characters in position 0-1: ordinal not in range(256)

我的腳本:

self.db=MySQLdb.connect("localhost", "usr", "pass", "dbName") 
    self.cursor=self.db.cursor() 
    args=("какой-то текст") #this is string in russian 
    self.cursor.callproc('pr_MyProc', args) 
    self.cursor.execute('SELECT @_pr_MyProc_2') #getting result from sp 
    result=self.cursor.fetchone() 
    self.db.commit() 

我讀過設置charset='utf8' shuld解決此問題,但是當我使用的字符串:

self.db=MySQLdb.connect("localhost", "usr", "pass", "dbName", charset='utf8') 

這給了我另一個錯誤;

UnicodeEncodeError: 'utf-8' codec can't encode character '\udcd1' in position 20: surrogates not allowed

另外我試圖設置參數use_unicode=True,這是行不通的。

+0

它的工作原理(u「какой-тотекст」)'? –

+0

@DanielRoseman不,我也試過了。 – Gleb

+0

是這個蟒蛇2或3? –

回答

5

更多的事情來檢查: http://mysql.rjweb.org/doc.php/charcoll#python

可能的項目:

  • 啓動代碼文件,# -*- coding: utf-8 -*- - (在代碼中的文字)
  • 字面應該是U '......'

你可以提取HEX? какой-то текст應該是這個在utf8中:D0BA D0B0 D0BA D0BE D0B9 2D D182 D0BE D182 20 D0B5 D0BA D181 D182

+2

據我所知「# - * - coding:utf-8 - * - 」設置文件的編碼,而不是字符串。所以它沒有幫助。 – Gleb

+0

它在你的情況下受傷了嗎? –

2

MySQLdb模塊與python 3不兼容。這可能是你遇到問題的原因。我建議使用不同的連接器,如PyMySQLmysqlclient

相關:23376103

+1

我正在使用mysqlclinet – Gleb

3

這裏有一些想法。也許不是一個迴應。我一直在玩蟒蛇/ MySQL的/ UTF-8/Unicode的過去,這是事情我記得:

看着Saltstack mysql的模塊的評論:

https://github.com/saltstack/salt/blob/develop/salt/modules/mysql.py#L314-L322

# MySQLdb states that this is required for charset usage 
# but in fact it's more than it's internally activated 
# when charset is used, activating use_unicode here would 
# retrieve utf8 strings as unicode() objects in salt 
# and we do not want that. 
#_connarg('connection_use_unicode', 'use_unicode') 
connargs['use_unicode'] = False 
_connarg('connection_charset', 'charset') 

我們請參閱以避免更改結果字符串use_unicode設置爲False,而charset(可能是utf-8)被設置爲參數。 use_unicode更像是一個'請求',以響應爲unicode字符串。

您可以在測試中檢查實際使用情況,這裏是: https://github.com/saltstack/salt/blob/develop/tests/integration/modules/test_mysql.py#L311-L361,數據庫名爲'標準語'。

現在關於消息UnicodeEncodeError:'utf-8'編解碼器無法編碼字符'\ udcd1'**。您正在使用** unicode,但您告訴模塊它是utf-8。它不是utf-8,直到你在utf-8中編碼你的unicode字符串。

也許你應該嘗試:

args=(u"какой-то текст".encode('utf-8')) 

至少在python3這是必需的,因爲你的 「какой-тотекст」 是不是UTF-8在默認情況下。

+0

現在鏈接已損壞:我找到了新的鏈接:https://github.com/saltstack/salt/blob/develop/tests/integration/modules/test_mysql.py#L311-L361(note file_name更改) – bdeo

+0

謝謝,鏈接已更新 – regilero

1

什麼是數據庫的字符集?
使用:

show variables like "characetr%"; 

或看到你的數據庫的字符集

2

也許你可以重新載入你的sysutf-8,並嘗試將字符串解碼成utf-8如下:

import sys 
reload(sys) 
sys.setdefaultencoding("utf-8") 

... 

stringUtf8 = u''.join(string_original).decode('utf-8') 
1

我看到這裏有兩個問題。

  1. 你有unicode,但你嘗試通過設置參數「charset」來定義它爲utf-8。您應該先將Unicode編碼爲utf-8或其他編碼系統。

  2. 如果它不起作用,請嘗試使用init_command ='SET NAMES UTF8'參數。

所以它看起來像:

conn = MySQLdb.connect(charset='utf8', init_command='SET NAMES UTF8') 

你也可以這樣試試:

cursor = db.cursor() 

cursor.execute("SET NAMES UTF8;") 
2

我有一個類似的問題,最近,但在PostgreSQL。在嘗試了大量來自SO/Internet的建議後,我意識到問題出在我的數據庫上。我不得不放棄我的數據庫並重新安裝Postgres,因爲出於某種原因,它不允許我更改數據庫的默認排序規則。我很匆忙,所以找不到更好的解決方案,但會推薦相同的,因爲我只是在部署環境中啓動我的應用程序。 一切順利。

0

我遇到了類似的問題,這是由於數據庫中無效的utf-8數據造成的;似乎MySQL不關心這個,但是Python做,因爲這是繼UTF-8的規格,它說that

  • 代理對中無法使用UTF-8
  • 不成對的代理人都沒有允許在utf-8中

如果你想「讓它工作」,你將不得不截獲MySQL數據包並使用你自己的轉換器來執行臨時替換。

這裏的「處理」含代理人無效數據的一種方法:

def borked_utf8_decode(data): 
    """ 
    Work around input with unpaired surrogates or surrogate pairs, 
    replacing by XML char refs: look for "&#\d+;" after. 
    """ 
    return data.decode("utf-8", "surrogatepass") \ 
    .encode("utf-8", "xmlcharrefreplace") \ 
    .decode("utf-8") 

注意處理的正確方法是上下文相關,但也有一些共同的替代方案中,像this one

而且這裏有一個方法插入到pymysql這個的(另一種方式是猴子補丁場處理,例如見https://github.com/PyMySQL/PyMySQL/issues/631):`ARGS =:

如果你的unicode字符串發送
import pymysql.converters 

# use this in your connection 
pymysql_use_unicode = False 
conversions = pymysql.converters.conversions 
conversions[pymysql.converters.FIELD_TYPE.STRING] = borked_utf8_decode 
conversions[pymysql.converters.FIELD_TYPE.VAR_STRING] = borked_utf8_decode 
conversions[pymysql.converters.FIELD_TYPE.VARCHAR] = borked_utf8_decode