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

使用cx_Oracle連接Python與Oracle的問題

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

import pandas as pd
import cx_Oracle
import os

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

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

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

    #SQL語句,可以定制,實現(xià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") # 可以得到結果集

執(zhí)行到conn = cx_Oracle.connect("c##scott", "tiger", dsn)會報錯:DatabaseError: ORA-12505: TNS: 監(jiān)聽程序當前無法識別連接描述符中所給出的 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))
    )
  )
  

通過sqlplus的select instance_name from v$instance;也確定過sid的名稱正確無誤:
圖片描述

請問是哪里出錯了?如何解決?

回答
編輯回答
尤禮

老哥首先你的SID沒有問題 ,排查思路:

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

2.我是昨天研究的 ,你的pandas 學習了 pd.read_sql(sql,conn) 這個寫法待驗證 ,是我get 到的點

3.我遇到的問題是在ubuntu用pycharm里寫代碼無法連接oracle數(shù)據(jù)庫 ,但pycharm 自帶的工具可以連接,在shell里也可以正常連接 最后也沒有找到原因 一直報錯說是不是64位客戶端 ,但我所有的包都是64位的,待解決。。。

4.最后附上干貨,我的連接demo 以及將數(shù)據(jù)寫入到csv文件,僅供參考,老哥記得回復我,維護社區(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