背景:工作需要氯迂,windows環(huán)境下要用python連接oracle,用pandas處理數(shù)據(jù)言缤。
目標(biāo):連接oracle嚼蚀,并讀取為DataFrame格式。
連接oracle是個(gè)大坑管挟,嘗試了很久終于整好了轿曙,總結(jié)一下中途發(fā)現(xiàn)的問題。
1、下載cx_oracle包
遇事不決导帝,先下包守谓。
pip install cx_Oracle
安好以后興致勃勃的執(zhí)行一下代碼
import cx_Oracle
conn = cx_Oracle.connect('用戶名/密碼@主機(jī)ip地址:端口號(hào)/SID')
c = conn.cursor()
x = c.execute('select sysdate from dual')
x.fetchall()
c.close()
conn.close()
然后不出意料的報(bào)錯(cuò)
報(bào)錯(cuò):cx_Oracle.DatabaseError: DPI-1047: 64-bit Oracle Client library cannot be loaded: "The specified module could not be found".
2、安裝 instant client
查詢后發(fā)現(xiàn)需要整上 instant client您单,又要分兩種情況:
1斋荞、已安裝oracle客戶端
2、未安裝oracle客戶端(需要連接服務(wù)器數(shù)據(jù)庫(kù)的情況
我是屬于第二種情況虐秦,第一種情況移步此處平酿。
2.1、直接上 oracle官網(wǎng) [下載](https://www.oracle.com/technetwork/cn/topics/winx64soft-101515-zhs.html)悦陋。
或復(fù)制文件下載鏈接:https://download.oracle.com/otn/nt/oracle11g/112010/win64_11gR2_client.zip?AuthParam=1571646862_b88d6693cf92e9d501e6a4d14c58d462
下載完成后解壓安裝蜈彼,選擇對(duì)應(yīng)的文件安裝。
2.2叨恨、再點(diǎn)擊下載這個(gè)壓縮包柳刮。
下載回是一個(gè)壓縮文件,解壓之后的文件夾叫 instantclient_11_2挖垛。
2.2.1痒钝、創(chuàng)建路徑:D:/Oracel/product/11.2.0
2.2.2、然后把instantclient_11_2丟進(jìn)去痢毒。
2.2.3送矩、將文件中后綴為 dll 的文件復(fù)制到 anaconda 或者python 安裝位置。
2.2.4哪替、把以下3個(gè)程序放進(jìn)python安裝文件夾里的 Anaconda3\Lib\site-packages 中:
oci.dll
oraocci1.dll
oraociei1.dll
2.2.5栋荸、在D:/instantclient_11_2目錄下新建目錄network
2.2.4、在network目錄下再新建admin目錄,在admin目錄下新建文件tnsnames.ora,使用文本編輯器打開寫入如下內(nèi)容:
里面的HOST凭舶,PORT晌块,MWDB根據(jù)個(gè)人情況填寫
MWDB=
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.58)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = SID)
)
)
2.2.5、添加一個(gè)環(huán)境變量帅霜,名為TNS_ADMIN匆背,值為tnsnames.ora文件所在路徑。比如我的本機(jī)為:D:/Oracel/product/11.2.0/instantclient_11_2/network/admin
2.2.6身冀、再修改系統(tǒng)環(huán)境變量钝尸,D:/Oracel/product/11.2.0/instantclient_11_2。
2.2.7搂根、設(shè)置ORACLE的語(yǔ)言珍促,添加環(huán)境變量NLS_LANG ,值為SIMPLIFIED CHINESE_CHINA.ZHS16GBK。
如果不清楚遠(yuǎn)程數(shù)據(jù)庫(kù)的ORACLE 語(yǔ)言剩愧,可以ssh或者telnet到遠(yuǎn)程機(jī)器,在命令界面輸入猪叙,用命令行連接到數(shù)據(jù)庫(kù)。
select value from nls_database_parameters where parameter='NLS_CHARACTERSET'
結(jié)果 | NLS_LANG 值 |
---|---|
ZHS16GBK | SIMPLIFIED CHINESE_CHINA.ZHS16GBK |
AL32UTF8 | SIMPLIFIED CHINESE_CHINA.AL32UTF8 |
3、再次嘗試連接
import cx_Oracle
conn = cx_Oracle.connect('用戶名/密碼@主機(jī)ip地址:端口號(hào)/SID')
然后報(bào)錯(cuò) # # # 報(bào)錯(cuò):ORA-12514: TNS:
WDNMD Q妗3上础!
查詢后發(fā)現(xiàn)是服務(wù)名有問題藏否,即上面的SID填寫錯(cuò)誤瓶殃。
OK,上數(shù)據(jù)庫(kù)查詢服務(wù)名
select value from v$parameter where name like 'service_name%'
我查出來是 oracle_docker
然后修改后填入
conn = cx_Oracle.connect('用戶名/密碼@主機(jī)ip地址:端口號(hào)/oracle_docker')
然后可以正常讀取出數(shù)據(jù)了8鼻R4弧!淆储。
(PS:網(wǎng)上參考資料冠场,部分操作后需要重新啟動(dòng)Python才有效果)
4、pandas讀取oracle
import cx_Oracle
import os
import pandas as pd
os.environ['NLS_LANG'] = 'SIMPLIFIED CHINESE_CHINA.ZHS16GBK'
conn = cx_Oracle.connect('UziSB/Uzi4800@192.168.0.58:1521/oracle_docker')
print (conn.version)
c = conn.cursor()
x = c.execute('select * from dual')
y = x.fetchall()
z = pd.DataFreme(y)
c.close()
conn.close()
print (z)
會(huì)發(fā)現(xiàn)一個(gè)問題本砰,獲取的數(shù)據(jù)沒有columns名稱碴裙。
那么就只有用Python連接數(shù)據(jù)庫(kù)的好♂伙♂伴:sqlalchemy
import cx_Oracle
import os
import pandas as pd
from sqlalchemy import creat_engine
conn = creat_engine('UziSB/Uzi4800@192.168.0.58:1521/oracle_docker')
sql = "select * from dual"
z = pd.read_sql(sql , conn)
print (z)