問題與原因
使用python執行插入語句將數據插入到MySQL時拋出了以下異常
pymysql.err.InternalError: (1366, "Incorrect string value: '\\xF0\\x9F\\x91\\x8D, ...' for column 'content' at row 1")
以上錯誤是由編碼問題造成的,你使用的數據庫默認編碼是utf8,可以保存1到3個字節,但是你插入到數據庫中的字符串包含emoji表情字符(占用4個字節),因此會拋出Incorrect string value異常。
解決方法
解決的方法主要有以下兩種
- 修改MySQL的編碼格式
- 在程序中過濾emoji表情字符
修改MySQL的編碼格式
MySQL從5.5.3版本開始,才支持4個字節的utf8編碼,編碼名稱是utf8mb4(mb4意思為max bytes 4),在MySQL中執行以下SQL語句可以看到utf8和utf8mb4的相關信息
SELECT * FROM information_schema.CHARACTER_SETS
WHERE CHARACTER_SET_NAME LIKE 'utf8%'
結果如下
CHARACTER_SET_NAME | DEFAULT_COLLATE_NAME | DESCRIPTION | MAXLEN |
---|---|---|---|
utf8 | utf8_general_ci | UTF-8 Unicode | 3 |
utf8mb4 | utf8mb4_general_ci | UTF-8 Unicode | 4 |
因此,將MySQL編碼改為utf8mb4就可以解決這個問題。
解決程序的編碼問題需要進行以下幾個操作:
-
修改my.cnf配置
找到MySQL的配置文件my.cnf(windows系統一般在MySQL的安裝目錄中,linux系統放在/etc目錄下)
修改含有utf8編碼的參數為utf8mb4,如下
character-set-server=utf8mb4 [client] default-character-set=utf8mb4 [mysql] default-character-set=utf8mb4
修改保存后,重啟MySQL。
-
修改數據庫和數據表的編碼格式
修改數據庫編碼(更改
db_name
為你的數據庫)ALTER DATABASE `db_name` CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
修改數據表編碼(更改
table_name
為你的數據表)。ALTER TABLE `table_name` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-
修改python連接pymysql的配置信息
去掉
charset
參數或將charset
參數設置為utf8mb4,如:MYSQL_CONFIG = { 'host': 'localhost', # IP地址 'port': 3306, # 端口 'user': 'root', # 用戶名 'passwd': '123456', # 密碼 'db': 'mydb', # 數據庫 # 'charset': 'utf8mb4', # 字符編碼 }
再次執行你的程序就可以正常插入數據了。
在程序中過濾emoji表情字符
為了避免出現以上錯誤,我們還可以在插入數據前對數據進行清洗,過濾掉文本中的emoji表情字符,再將數據插入到表中。
要去掉文本中的emoji表情字符可以使用以下兩種方法
自定義清除方法
def filter_emoji(desstr,restr=''):
#過濾表情
try:
co = re.compile(u'[\U00010000-\U0010ffff]')
except re.error:
co = re.compile(u'[\uD800-\uDBFF][\uDC00-\uDFFF]')
return co.sub(restr, desstr)
插入數據前先執行以上方法過濾emoji表情,如
content = '👍, very good!'
print(filter_emoji(content))
執行結果如下:
, very good!
使用emoji第三方包
安裝
pip3 install emoji
或
python3 -m pip install emoji
官方應用示例如下:
>> import emoji
>> print(emoji.emojize('Python is :thumbs_up:')) # 編碼
Python is 👍
>> print(emoji.emojize('Python is :thumbsup:', use_aliases=True))
Python is 👍
>> print(emoji.demojize('Python is 👍')) # 解碼
Python is :thumbs_up:
>>> print(emoji.emojize("Python is fun :red_heart:"))
Python is fun ❤
>>> print(emoji.emojize("Python is fun :red_heart:",variant="emoji_type"))
Python is fun ❤️ #red heart, not black heart
從上面例子可知,我們可以使用demojize()方法來處理emoji表情,demojize()方法的作用是將特殊字符轉換為正常字符(相當於解碼)。
import emoji
content = '👍, very good!'
print(emoji.demojize(content))
執行結果如下
:thumbs_up:, very good!
因此,我們就可以將解碼后的文本插入到MySQL數據庫中。
總結
以上就是Incorrect string value異常產生的原因和解決方法。如果對文本要求不大,本人比較推薦第二種方法,過濾emoji表情字符后再插入到數據庫中。否則,就需要修改相關的數據庫配置來解決這個問題。