最近使用python處理文本數據導入oracle數據庫。因爲數據庫是gbk編碼的,致使處理文件編碼問題困擾我兩天的時間。
我用了兩個白天加兩個晚上研究,程序直接在linux下用python運行程序成功,加入crontab後運行不成功,一開始覺得是linux環境變量問題。
再嘗試了各類辦法未解後,在凌晨2點忽然想到,既然可以運行,而且報錯是出如今執行sql語句的時候,那麼環境變量應該沒問題,應該仍是鏈接數據庫insert的時候出現問題。
由此,把問題重點轉移到了cx_oracle上面。也就是經過cx_oracle向數據庫插入數據是出現編碼問題。這個我也經過select時候中文亂碼,驗證了判斷問題點正確,
至此,問題的解決方案就很明瞭啦!我只須要在cx_oracle客戶端編碼設定和數據庫的編碼一致就能夠了。
如下是從網上查找到的設定客戶端cx_oracle編碼的方法:
用python鏈接Oracle須要處理數據導出,和txt文件數據導入數據庫,導出是中文老是亂碼,文件導入數據庫是,中文數據就會報錯,提示編碼錯誤。
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-5: ordinal not in range(128)
最後發現是oracle客戶端的字符編碼設置不對。
要解決此問題須要一下兩個方面注意處理:
一、根據數據庫不一樣的編碼設定,編寫的python腳本中須要相對應的加入以下幾句:
import os
os.environ['NLS_LANG'] = 'SIMPLIFIED CHINESE_CHINA.UTF8'
或者
os.environ['NLS_LANG'] = 'SIMPLIFIED CHINESE_CHINA.ZHS16GBK'
這樣select出來的中文顯示沒有問題。
二、要可以正常的insert和update中文,還須要指定python源文件的字符集密碼和oracle一致。
------------------------------------------------------------------------------- html
例子:python
- # -*- coding: utf-8 -*-
-
- import os
- os.environ['NLS_LANG'] = 'SIMPLIFIED CHINESE_CHINA.UTF8' #或者os.environ['NLS_LANG'] = 'AMERICAN_AMERICA.AL32UTF8'
-
-
-
- import cx_Oracle
- db = cx_Oracle.connect(username/passwd@host:port/sevicename)
- cursor = db.cursor()
- #其餘操做
-
- db.commit()
- db.close()
參考:linux
客戶端的NLS_LANG設置及編碼轉換sql
①在Oracle客戶端向服務器端提交SQL語句時,Oracle客戶端根據NLS_LANG和數據庫字符集,對從應用程序接傳送過來的字符串編碼進行轉換處理。若是NLS_LANG與數據庫字符集相同,不做轉換,不然要轉換成數據庫字符集並傳送到服務器。服務器在接收到字符串編碼以後,對於普通的CHAR或VARCHAR2類型,直接存儲;對於NCHAR或NVARCHAR2類型,服務器端將其轉換爲國家字符集再存儲。數據庫
①在Oracle客戶端向
服務器端提交SQL語句時,Oracle客戶端根據NLS_LANG和數據庫字符集,對從應用程序接傳送過來的字符串編碼進行轉換處理。若是NLS_LANG與數據庫字符集相同,不做轉換,不然要轉換成數據庫字符集並傳送到
服務器。服務器在接收到字符串編碼以後,對於普通的CHAR或VARCHAR2類型,直接存儲;對於NCHAR或NVARCHAR2類型,服務器端將其轉換爲國家字符集再存儲。