1. 程式人生 > >python報OperationalError: (1366, "Incorrect string value..."的問題解決

python報OperationalError: (1366, "Incorrect string value..."的問題解決

日常 數據 round 包含 default utf per .sh ngx

一、環境及問題描述

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..."的問題解決