python操作Oracle數(shù)據(jù)庫

我們有一個系統(tǒng)因為每個月要提供統(tǒng)計數(shù)據(jù)表格,為了方便統(tǒng)計我用python寫了一個統(tǒng)計腳本,運(yùn)行腳本就可以生成統(tǒng)計表格,特別方便。?最近離職在交接工作,要幫同事配置相關(guān)環(huán)境,所以我就把去年的這篇文章又翻了出來,我記得之前公眾號上發(fā)過,但是我搜了下,沒找到,可能記錯了,但是素材庫確實(shí)有,好吧,權(quán)當(dāng)記錯了,我重新發(fā)一下,各位小伙伴也可以參考下。?懂點(diǎn)python工作效率真的可以提高很多,如果這些數(shù)據(jù)每次都手動統(tǒng)計的話,至少十分鐘,但是如果用腳本的話30s搞定,效率賊高,省下這寶貴的九分三十秒我又可以愉快地寫bug了,以下是之前發(fā)送內(nèi)容的全文:
python操作Oracle數(shù)據(jù)庫
利用這漫長的假期,我又一次拾起來已經(jīng)放棄了很多次的python,開始了一波新的嘗試,不過慶幸的是,這一次好像多少有了一點(diǎn)眉目,感覺開始入門了(我承認(rèn),我一開始對python有成見),所以我就開始了新的嘗試,也有了新的收獲,也有了今天這兩篇博客。
安裝cx_Oracle
cx_Oracle相當(dāng)于python的Oracle數(shù)據(jù)庫的驅(qū)動,必須有驅(qū)動才能連接Oracle數(shù)據(jù)庫,具體方法如下:
方法一:直接在官方網(wǎng)站下載,然后安裝
https://pypi.org/project/cx-Oracle/
選擇對應(yīng)的系統(tǒng)及版本,然后下載安裝
方法二:通過pip安裝
pip?install?cx-Oracle
我是同第二種方式安裝,可以通過如下方式檢查自己是否已經(jīng)安裝,以及安裝的版本信息:
?pip?show?-f?cx-Oracle
添加Oracle客戶端配置
下載Oracle數(shù)據(jù)庫對應(yīng)的客戶端
查看數(shù)據(jù)庫版本
可以通過如下sql查看版本信息:
select * from v$version;
比如我的Oracle數(shù)據(jù)庫版本號為:
1?Oracle?Database?11g?Enterprise?Edition?Release?11.2.0.4.0?-?64bit?Production
2?PL/SQL?Release?11.2.0.4.0?-?Production
3?"CORE?11.2.0.4.0?Production"
4?TNS?for?Linux:?Version?11.2.0.4.0?-?Production
5?NLSRTL?Version?11.2.0.4.0?-?Production
下載數(shù)據(jù)庫客戶端
具體下載地址如下:
https://www.oracle.com/cn/database/technologies/instant-client/downloads.html
選擇對應(yīng)的操作系統(tǒng)和版本,當(dāng)然必須得和你的python版本一致(64Bit/32Bit)
因為我的數(shù)據(jù)庫版本是:11.2.0.4.0,所以我下載的客戶端版本也是這個版本instantclient-basic-windows.x64-11.2.0.4.0.zip
然后解壓,并將解壓后的地址信息加入到操作系統(tǒng)環(huán)境變量中,比如我的文件夾路徑為:
E:\app\myUserName\product\11.2.0_64bit
那么,我的環(huán)境變量設(shè)置如下:
上面的環(huán)境變量是添加在path這個變量底下的。
配置TNS
創(chuàng)建tnsnames.ora
進(jìn)入如下目錄,并創(chuàng)建tnsnames.ora文件。如果沒有可以手動創(chuàng)建(我是之前安裝過完整版客戶端,所以已經(jīng)有了,我從已經(jīng)安裝過的目錄下直接拷貝,之前安裝的是32Bit)
E:\app\myUserName\product\11.2.0_64bit\network\admin
也有人說可以在上面添加的環(huán)境變量的目錄下直接創(chuàng)建這個文件(即E:\app\myUserName\product\11.2.0_64bit),我沒有嘗試過,如果有小伙伴試過了可行,請告訴我,謝謝!
配置數(shù)據(jù)庫信息
打開剛剛創(chuàng)建的tnsnames.ora文件,加入你的數(shù)據(jù)庫連接配置(TNS配置):
ORCL?=
??(DESCRIPTION?=
????(ADDRESS?=?(PROTOCOL?=?TCP)(HOST?=?host)(PORT?=?1522))
????(CONNECT_DATA?=
??????(SERVER?=?DEDICATED)
??????(SERVICE_NAME?=?orcl)
??????(INSTANCE_NAME?=?orcl1)??????
????)
??)
你如果有用ql/sql的話,對這個文件應(yīng)該不陌生,host就是你的數(shù)據(jù)庫ip地址,PORT就是數(shù)據(jù)庫端口,SERVER一般應(yīng)該都一樣(我猜的),SERVICE_NAME和INSTANCE_NAME應(yīng)該是你創(chuàng)建數(shù)據(jù)庫的時候設(shè)置的,沒創(chuàng)建過Oracle數(shù)據(jù)庫,我只負(fù)責(zé)用??。
添加完以上配置信息,然后就該開始編寫我們的測試腳本了
編寫python腳本
腳本很簡單,就幾行代碼:
#!/usr/bin/env?python
import?cx_Oracle
#?格式:用戶名/密碼@主機(jī):端口/SERVICE_NAME
con?=?cx_Oracle.connect('userName/Password@host:1522/orcl')?
#?格式:用戶名,密碼,主機(jī):端口/SERVICE_NAME
con2?=?cx_Oracle.connect('userName',?'Password',?'host:1522/orcl')?
print(con.version)
print(con2.version)
這里解釋下,其實(shí)也不用解釋,因為確實(shí)很簡單。引入cx_Oracle,然后獲取數(shù)據(jù)庫連接,打印數(shù)據(jù)庫版本。獲取數(shù)據(jù)庫有兩種方式,區(qū)別不大,都是將用戶名、密碼、主機(jī)、端口、服務(wù)傳入,然后獲取數(shù)據(jù)庫連接。
遇到的問題
如果你能正常打印數(shù)據(jù)庫版本信息,那么恭喜你,第一次就如此完美的取得成功。很多人,包括我,在進(jìn)行以上步驟都遇到了很多問題,說下我的問題,報錯信息如下:
cx_Oracle.DatabaseError:?DPI-1047:?64-bit?Oracle?Client?library?cannot?be?loaded:??"libclntsh.so:?cannot?open?shared?object?file:?No?such?file?or?directory".?See?https://oracle.github.io/odpi/doc/installation.html#linux?for?help
和以上錯誤很類似,因為沒保留錯誤信息,所以我大概根據(jù)瀏覽器歷史記錄查了下。我查詢的結(jié)果是說python版本和Oracle數(shù)據(jù)庫客戶端版本不一致,因為我的python是64位的,數(shù)據(jù)庫客戶端版本是32位,然后我下載64位客戶端,并替換了環(huán)境變量,重啟了電腦,依然不行,幾經(jīng)折騰,最后我發(fā)現(xiàn)有篇博客說是需要在python安裝根目錄下復(fù)制Oracle配置的dll文件,想嘗試的時候,發(fā)現(xiàn)文件夾沒權(quán)限,最后忍無可忍,我把python重新安裝(3.8),然后安裝pip并重新安裝cx-Oracle(cx_Oracle-7.3.0,pip直接安裝),竟然神奇的好了,嗯~ o( ̄▽ ̄)o還好我沒放棄??
完善腳本,執(zhí)行查詢
完成以上步驟,說明我們已經(jīng)完成了python連接Oracle數(shù)據(jù)庫的配置工作,接下來我們將了解如何執(zhí)行sql語句,并獲取返回結(jié)果。其實(shí),也很簡單,參照如下代碼即可。
?#?獲取數(shù)據(jù)庫游標(biāo)對象
????cursor=?connection.cursor()
????#?sql參數(shù)集
????params?=?{'aapid':?aapid,'yearMonth':'2020-02'}
????#?sql
????sql?=?'''SELECT?*?FROM?log?WHERE?CreateTime?like?:yearMonth||'%'
????AND?aapid=:aapid?'''
????#?執(zhí)行sql
????query?=?cursor.execute(sql,?params)
?#?獲取查詢結(jié)果集
????rows?=?cursor.fetchall()??
?#?獲取結(jié)果列(數(shù)據(jù)庫字段名)
????titles?=?cursor.description?
????print(rows)
????print(titles)
執(zhí)行以上代碼,即可打印sql查詢到的結(jié)果集。需要注意的是,sql查詢參數(shù)集是通過字典的形式導(dǎo)入的,然后在sql中通過: + 鍵名的方式傳入?yún)?shù)。
當(dāng)然能執(zhí)行sql的方法不止上面的一種,比如你需要入?yún)⒌臅r候,可以通過如下方式執(zhí)行查詢:
sql?=?"select?*?from?test?limit?10"??#?在test表中取出十條數(shù)據(jù)
search_count?=?cursor.execute(sql)
有關(guān)其他的插入、更新、刪除、建表等操作,后續(xù)再繼續(xù)進(jìn)行深入探索,主要是我現(xiàn)在也不會啊??好了,今天就到這里吧,不早了,早點(diǎn)休息吧,晚安,好夢!
- END -