python報OperationalError: (1366, "Incorrect string value..."的問題解決
一、環境及問題描述
1. 環境
操作系統:win10,64bit。
python版本:2.7.15
mysql版本:5.7.23
2. 問題描述
使用python從某個數據文件讀取數據,處理後,用MySQLdb去連接數據庫表並插入數據,此時報錯:
OperationalError: (1366, "Incorrect string value..."
網上可以查到是編碼問題:
出現這個異常是mysql問題,而非python的問題,這是因為mysql的字段類型是utf-xxx, 而在mysql中這些utf-8數據類型只能存儲最多三個字節的字符,而存不了包含四個字節的字符。
因為之前的數據庫的字符集是utf8,所以需要轉為utf8mb4編碼。
不幸的是,我裝的mysql版本很老,是5.4的版本,而utf8mb4編碼在5.5.3後才支持,於是只能重裝mysql,重新裝的是5.7.23的版本。
二、關於utf8mb4編碼
MySQL在5.5.3版本之後增加了這個utf8mb4的編碼,mb4就是most bytes 4的意思,專門用來兼容四字節的unicode。其實,utf8mb4是utf8的超集,理論上原來使用utf8,然後將字符集修改為utf8mb4,也會不會對已有的utf8編碼讀取產生任何問題。當然,為了節省空間,一般情況下使用utf8也就夠了。
既然utf8應付日常使用完全沒有問題,那為什麽還要使用utf8mb4呢? 低版本的MySQL支持的utf8編碼,最大字符長度為 3 字節,如果遇到 4 字節的字符就會出現錯誤了。
三個字節的 UTF-8 最大能編碼的 Unicode 字符是 0xFFFF,也就是 Unicode 中的基本多文平面(BMP)。也就是說,任何不在基本多文平面的 Unicode字符,都無法使用MySQL原有的 utf8 字符集存儲。
三、問題解決
1. 數據庫編碼修改
修改my.ini的內容:
[client] default-character-set = utf8mb4 [mysql] default-character-set = utf8mb4 [mysqld] character-set-client-handshake = FALSE character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci init_connect=‘SET NAMES utf8mb4‘
將數據庫和已經建好的表也轉換成utf8mb4:
ALTER DATABASE db_name CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
更改表編碼:
ALTER TABLE TABLE_NAME CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
重啟mysql服務。
如果這個時候已經解決問題,可以不用往下看了。
否則,可以看看下面的思路能否為你提供一點想法。
我的情況是依舊沒有解決問題。
2. 從讀取文件的編碼入手
發現數據文件的編碼是gb2312,所以讀取一行內容後需要轉為unicode然後再轉為utf8:
line = line.decode(‘gbk‘).encode(‘utf-8‘)
(奇怪的是用’gb2312’就不行)
至此問題解決。
所以可以看出實際上我遇到的問題只是讀取的編碼在寫入mysql的時候不能識別而已,後面我新建一個表,默認編碼為utf8,也能正常插入,這也驗證了這個想法。
四、參考
1. python插入數據到mysql時報錯:mysql
2. utf8mb4與utf8的區別
3. 更改MySQL數據庫的編碼為utf8mb4
(完)
python報OperationalError: (1366, "Incorrect string value..."的問題解決