最近在公司碰到一個異常蛋疼的情況,mysql數據庫中,數據庫和表的字符集都是'gbk',但是列的字符集卻是'latin1',於是蛋疼的事情出現了。
無論我連接字符串的`charset`設置為`gbk`,`utf8`,`latin1`中的任意一種,查詢出來的表中數據的中文都是亂碼,在查詢中加上如下代碼也還是無濟於事:
SET NAMES latin1 在更換各種py鏈接庫,然後瘋狂的google和問了各路大神之後,終於找到解決思路如下: 1、通過hex(column)將列中的數據2進制轉為16進制字符串表示,然後返回給py 2、py通過2次decode操作,將hex字符串轉為Unicode編碼 3、最後進行一次encode,將結果轉為utf8響應出去 偽代碼如下:def hex2char(hexString): output = hexString.decode('hex').decode('gbk').encode('utf8') return output ... sqlStr = "SELECT acc_name,level_n,hex(char_name) FROM roles where acc_name='noc20'" cur.execute(sqlStr) for c in cur: char_name = hex2char(c[2]) ...
最後分析一下為什麼之前,設置charset='gbk',然後對查詢結果直接decode('gbk')無法操作的原因,因為數據庫字符集和表的字符集都是`gbk`,所以數據庫鏈接我們這裡必須設定為`gbk`,但是由於我們需要獲取的列名字符集被坑爹的設置成`latin1`,所以查詢返回的字符串其實就是以`latin1`編碼的,實質上是`gbk`的字符串,當然使用任意一種decode都是無法正確轉換的,只有將字符串轉為2進制表示,才能無損的從數據庫讀出數據,而`hex`操作正巧幫我們無損的從數據庫將數據讀出,然後就順利成章的進行2次decode,最後獲得我們需要的字符串,最後再次譴責哪個坑爹設計了這樣的數據庫。