python mysql 编码方式,Python3编码与mysql编码介绍
Python3自詡解決了編碼問題,但還是有一系列的坑。本文就記錄下前幾天遇到的python3編碼問題。mysql編碼問題附帶介紹。
python3 json串的編碼
針對于包含中文的字典,如果想要正常顯示中文,在dumps時,需配置參數ensure_ascii=False。舉例:
a={"name":"中國"}
json.dumps(a)
'{"name": "\\u4e2d\\u56fd"}'
json.dumps(a,ensure_ascii=False)
'{"name": "中國"}'
針對于包含特定轉義字符的字符串,如果想要正常解析,需要在loads時配置strict=False。舉例:
json.loads('{"foo":"bar\nbaz"}')
Traceback (most recent call last):
File "", line 1, in
json.loads('{"foo":"bar\nbaz"}')
File "C:\Users\jonyguo\AppData\Local\Programs\Python\Python36\lib\json\__init__.py", line 354, in loads
return _default_decoder.decode(s)
File "C:\Users\jonyguo\AppData\Local\Programs\Python\Python36\lib\json\decoder.py", line 339, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "C:\Users\jonyguo\AppData\Local\Programs\Python\Python36\lib\json\decoder.py", line 355, in raw_decode
obj, end = self.scan_once(s, idx)
json.decoder.JSONDecodeError: Invalid control character at: line 1 column 12 (char 11)
json.loads('{"foo":"bar\nbaz"}', strict=False)
{'foo': 'bar\nbaz'}
python3的字符串編碼
python3中只有兩種字符串,一是str,一是bytes。str經過encode變成bytes,bytes經過decode變成str。
有時從網絡取出的包含中文的數據為unicode編碼的字符串,可通過先編碼在解碼轉化為中文:
a="\\u4e2d\\u56fd"
print(a)
\u4e2d\u56fd
a.encode().decode("unicode_escape")
'中國'
也可以通過repr將其轉化為字符串,將兩個反斜杠替換為一個反斜杠來解決這個問題:
a="\\u4e2d\\u56fd"
eval(repr(a).replace('\\\\', '\\'))
'中國'
python3 + apache的字符編碼問題
python3腳本作為cgi供前端界面調用。遇到了一個很奇怪的問題,我通過編寫的python腳本調用cgi時,編碼一切正常,但是當我通過http調用時會出現一些問題。從數據庫中取中文數據,返回前端顯示一切都正常。但是當我把數據庫中的中文與一些字符組成一個文件名,判斷文件是否存在時,一直報錯:UnicodeEncodeError: 'ascii' codec can't encode characters in position 46-49: ordinal not in range(128)。
剛開始以為是apache的編碼問題,后來查看apache的編碼也確定是utf8,不知所措。經google,查找到了原因。
https://www.raspberrypi.org/forums/viewtopic.php?t=65257 這個帖子里面有介紹到說:
The difference is that from the command line Python inherits your locale settings (probably LANG=fr_FR.UTF-8), whereas from Apache it inherits LANG=C. It knows that your strings are Unicode, but it can not print them in an ASCII environment.
說是通過python腳本調用的時候python繼承的是locale 設置,為utf8,可正常顯示(個人感覺這里可能說的有些不恰當,這里應該是采用python3自己的編碼)。而apache繼承的是LANG=C,為ascii,無法正常顯示。按照其配置,在/etc/apache2/envvars中添加. /etc/default/locale(/etc/sysconfig/i18n)即可。配置后發現依然無法解決問題。
后又繼續google,找到了解決方案。
https://stackoverflow.com/questions/9322410/set-encoding-in-python-3-cgi-scripts
Add PassEnv LANG line to the end of your /etc/apache2/apache2.conf or .htaccess.
Uncomment . /etc/default/locale line in /etc/apache2/envvars.
Make sure line similar to LANG="en_US.UTF-8" is present in /etc/default/locale.
就是在apache2的配置文件中添加一行:PassEnv LANG 即可。要確保LANG為utf8。
mysql編碼問題
查看當前的數據庫編碼:
mysql> show variables like 'character%';
+--------------------------+--------------------------------------------------------------+
| Variable_name | Value |
+--------------------------+--------------------------------------------------------------+
| character_set_client | latin1 |
| character_set_connection | latin1 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | latin1 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /usr/local/mysql-5.1.46-linux-x86_64-glibc23/share/charsets/ |
+--------------------------+--------------------------------------------------------------+
從上圖可知,數據庫的編碼為utf8.
● character_set_client:無論客戶端傳遞的是什么編碼的數據,服務器都當成該編碼來處理,例如該編碼為UTF8,那么如果客戶端發送過來的數據不是UTF8,那么就會出現亂碼;
● character_set_connection:通過該編碼與client一致!該編碼不會導致亂碼!當執行的是查詢語句時,客戶端發送過來的數據會先轉換成connection指定的編碼。但只要客戶端發送過來的數據與client指定的編碼一致,那么轉換就不會出現問題;
● character_set_database:數據庫默認編碼,在創建數據庫時,如果沒有指定編碼,那么默認使用database編碼;
● character_set_filesystem:可以理解為文件的最終存儲形式,是二進制形式的;
● character_set_server:MySQL服務器默認編碼;
● character_set_results:MySQL會把數據轉換成該編碼后,再發送給客戶端,例如該編碼為UTF8,那么如果客戶端不使用UTF8來解讀,那么就會出現亂碼,說明客戶端必須使用result指定的編碼來解碼;
一條數據庫連接的過程如下:
client --> connection --> server --> connection --> result
其實只要保證client、connection和result 一致就不會出現亂碼問題。
通過set names utf8 保證client、connection和result 的編碼一致:
mysql> show variables like 'character%';
+--------------------------+--------------------------------------------------------------+
| Variable_name | Value |
+--------------------------+--------------------------------------------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /usr/local/mysql-5.1.46-linux-x86_64-glibc23/share/charsets/ |
+--------------------------+--------------------------------------------------------------+
總結
以上是生活随笔為你收集整理的python mysql 编码方式,Python3编码与mysql编码介绍的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: matlab intergral,mat
- 下一篇: python示例库,常用的Python库