鍍金池/ 問(wèn)答/Python  數(shù)據(jù)庫(kù)/ 使用cx_Oracle連接Python與Oracle的問(wèn)題

使用cx_Oracle連接Python與Oracle的問(wèn)題

想用Python提取本機(jī)Oracle數(shù)據(jù)庫(kù)中,#cscott用戶(hù)下的emp數(shù)據(jù)表,執(zhí)行如下程序:

import pandas as pd
import cx_Oracle
import os

#設(shè)置環(huán)境編碼方式,可解決讀取數(shù)據(jù)庫(kù)亂碼問(wèn)題
os.environ['NLS_LANG'] = 'SIMPLIFIED CHINESE_CHINA.UTF8'

#實(shí)現(xiàn)查詢(xún)并返回dataframe
#使用query(數(shù)據(jù)表名稱(chēng))獲取數(shù)據(jù)表:
#獲取本地IP
#import socket
#localhost = socket.gethostbyname(socket.gethostname())
def query(table):
    host = "localhost"    #數(shù)據(jù)庫(kù)ip 非C:\app\413022472\product\12.2.0\dbhome_1\network\admin\litsener.ora中的HOST(機(jī)器名)
    port = "1521"     #端口
    sid = "orcl"    #數(shù)據(jù)庫(kù)名稱(chēng) 登陸sqlplus,輸入select instance_name from v$instance;可獲取
    dsn = cx_Oracle.makedsn(host, port, sid)

    #scott是數(shù)據(jù)用戶(hù)名,tiger是登錄密碼(默認(rèn)用戶(hù)名和密碼)
    conn = cx_Oracle.connect("c##scott", "tiger", dsn)  

    #SQL語(yǔ)句,可以定制,實(shí)現(xiàn)靈活查詢(xún)
    sql = 'select * from '+ table 

    # 使用pandas的read_sql函數(shù),可以直接將數(shù)據(jù)存放在dataframe中
    results = pd.read_sql(sql,conn) 

    conn.close
    return results

test_data = query("emp") # 可以得到結(jié)果集

執(zhí)行到conn = cx_Oracle.connect("c##scott", "tiger", dsn)會(huì)報(bào)錯(cuò):DatabaseError: ORA-12505: TNS: 監(jiān)聽(tīng)程序當(dāng)前無(wú)法識(shí)別連接描述符中所給出的 SID

listner.ora文檔內(nèi)容如下:

# listener.ora Network Configuration File: C:\app\413022472\product\12.2.0\dbhome_1\network\admin\listener.ora
# Generated by Oracle configuration tools.

SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (SID_NAME = CLRExtProc)
      (ORACLE_HOME = C:\app\413022472\product\12.2.0\dbhome_1)
      (PROGRAM = extproc)
      (ENVS = "EXTPROC_DLLS=ONLY:C:\app\413022472\product\12.2.0\dbhome_1\bin\oraclr12.dll")
    )
  )

LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = DESKTOP-2RE9AJU.lan)(PORT = 1521))
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
    )
  )
  

通過(guò)sqlplus的select instance_name from v$instance;也確定過(guò)sid的名稱(chēng)正確無(wú)誤:
圖片描述

請(qǐng)問(wèn)是哪里出錯(cuò)了?如何解決?

回答
編輯回答
尤禮

老哥首先你的SID沒(méi)有問(wèn)題 ,排查思路:

  1. 你檢查的是你的tnsname.ora,這個(gè);連接文件 ,然后測(cè)試 在cmd 里正常用監(jiān)聽(tīng)登錄是否可以登錄

2.我是昨天研究的 ,你的pandas 學(xué)習(xí)了 pd.read_sql(sql,conn) 這個(gè)寫(xiě)法待驗(yàn)證 ,是我get 到的點(diǎn)

3.我遇到的問(wèn)題是在ubuntu用pycharm里寫(xiě)代碼無(wú)法連接oracle數(shù)據(jù)庫(kù) ,但pycharm 自帶的工具可以連接,在shell里也可以正常連接 最后也沒(méi)有找到原因 一直報(bào)錯(cuò)說(shuō)是不是64位客戶(hù)端 ,但我所有的包都是64位的,待解決。。。

4.最后附上干貨,我的連接demo 以及將數(shù)據(jù)寫(xiě)入到csv文件,僅供參考,老哥記得回復(fù)我,維護(hù)社區(qū)秩序。。

#!/usr/bin/python

import cx_Oracle as oracle
import csv
def oraclesql(cursor):
   #fp = open('D:/1.sql')
   #fp_sql = fp.read()
   cursor.execute("select * from emp")
   data = cursor.fetchall()
   #print (list(data))
   return list(data)
def write_to_csv(content):
    with open('oracle.csv','a') as csvfile:
        filename = ['empno','ename','job','mgr','hiredate','sal','comm','deptno']
        #filename = ['LOTS','ORG_ID','YEAR_TIME','NAME_PATIENT','GENDER','BIRTHDAY','AGE','RESIDENT_ID','HUKOU_ADDRESS']
        write = csv.writer(csvfile,delimiter=',')
        # write.writeheader()
        
        write.writerows([content])

 
 
if __name__ == '__main__':
   ipaddr = "127.0.0.1"
   username = "scott"
   password = "scott"
   oracle_port = "1521"
   oracle_service = "orcl"
   try:
      db = oracle.connect(username+"/"+password+"@"+ipaddr+":"+oracle_port+"/"+oracle_service)
    # 將異常捕捉
   except Exception as e:  
      print(e)
   else:
      cursor = db.cursor()
      data = oraclesql(cursor)
      for i in data:
          text = list(i)
          #print(text)
          write_to_csv(text)
      cursor.close()
      db.close()
      
2017年3月2日 13:38