Mit der cx_Oracle (http://cx-oracle.sourceforge.net/) Library lässt sich einfach die Oracle Datenbank in Python einbinden.
Eine Oracle OCI Client Umgebung in der richtigen Bit Version und Oracle Version ist installiert!
Minimal ist dazu der „Oracle Instant Client“ notwendig, siehe ⇒ http://www.oracle.com/technetwork/database/features/instant-client/index-097480.html
In vielen Beispielen im Netz werden keine Bind Variablen verwendet, davon ist dringend abzuraten!
D.h. die SQL Statements werden als String Objekte „zusammen gebaut“ und dann ausgeführt!
Das ist eine der Hauptursachen für die ganzen SQL Injektion Problem in vielen Anwendungen!
Mehr dazu siehe hier: Alexander Kornbrust -Tutorial: Oracle SQL Injection in Webapps – Part I
Für Windows kann die Software mit einem Installer installiert werden.
Die neueste Python Library für die Oracle Datenbank von https://pypi.python.org/pypi/cx_Oracle landen
Auf die Bit Version achten! In meine Fall 32bit und 11g!
Über die Powershell MD5 checken:
cd C:\Users\gpipperr\Downloads [Reflection.Assembly]::LoadWithPartialName("System.Web") [System.Web.Security.FormsAuthentication]::HashPasswordForStoringInConfigFile("cx_Oracle-5.2-11g.win32-py2.7-2.exe","MD5") 67413C94BA8BCFD462315787CDCFE7BA
Toll, dies ist mal ein ganz anderer Hash als auf der Webseite angegeben …
Installer starten, und Library im jeweilgen Python Home installieren
Leider funktioniert mit installierten C++ Compiler (Fehler „error: Microsoft Visual C++ 10.0 is required (Unable to find vcvarsall.bat).“ )
.\python.exe -m pip install cx_Oracle
Voraussetzung:
Wieder über ⇒ https://pypi.python.org/pypi/cx_Oracle
Nach cygwin /tmp kopieren + MD5 Testen und entpacken:
md5sum cx_Oracle-5.1.3.tar.gz cd6ff16559cbc9c20087ec812c7092ab *cx_Oracle-5.1.3.tar.gz tar xfvz cx_Oracle-5.1.3.tar.gz cd ./cx_Oracle-5.1.3
# in das ausgepackte Verzeichnis wechseln cd /tmp/cx_Oracle-5.1.3 python setup.py build #Fehler gcc: Fehler: nicht erkannte Kommandozeilenoption »-mno-cygwin« error: command 'gcc' failed with exit status vi setup.py .. #nach mno-cygwin suchen und auskomentieren .... elif sys.platform == "cygwin": #extraCompileArgs.append("-mno-cygwin") .. # erneut aufrufen => python setup.py build cx_Oracle.c:10:17: schwerwiegender Fehler: oci.h: No such file or directory #include <oci.h> ^ # Oracle Home setzen aufgerufen export ORACLE_HOME=/cygdrive/d/oracle/product/11.2.0.3/dbhome_1 python setup.py build python setup.py install #Warnings ignorieren #ok! #teste mit Script weiter unten
Die EMP Tabelle abfragen:
import cx_Oracle # get client library version print "Oracle Client Library Version :: ", cx_Oracle.clientversion() #get the connection to the database connection = cx_Oracle.connect('scott/tiger@10.10.10.1/GPI') # Version der DB ausgeben print "Oracle Database Version ::", connection.version #Cursor auf die DB öffenen cursor = connection.cursor() #Cursor ausführen cursor.execute('select * from emp order by empno') # Ergebnis ausgeben: # simple #for result in cursor: # print result # extended fetch # for EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO in cursor.fetchall(): print "Values from DB:", EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO #Verbindung wieder schließen cursor.close() connection.close()
Problem: ORA-12557: TNS:protocol adapter not loadable
In einer Umgebung mit mehren Oracle Homes darauf achten das in der Umgebung keine Pfade gesetzt sind, die auf das andere Home als das gewünschte zeigen!
import cx_Oracle connection = cx_Oracle.connect('scott/tiger@10.10.10.1/GPI') # Cursor auf die DB oeffenen cursor = connection.cursor() # Cursor ausfuehren cursor.prepare('select * from emp where deptno=:1') # execute the statement on the statment above # NONE Parameter deptno = ("10", "20") for i in deptno: cursor.execute(None, {'1': i}) result = cursor.fetchall() print result #Verbindung wieder schliessen cursor.close() connection.close()
import cx_Oracle import sys # get client library version print "Oracle Client Library Version :: ", cx_Oracle.clientversion() connection = cx_Oracle.connect('scott/tiger@10.10.10.1/GPI') # Version der DB ausgeben print "Oracle Database Version ::", connection.version # Cursor auf die DB oeffenen cursor = connection.cursor() # Oracle dept table has this columns # DEPTNO # DNAME # LOC dept_rows = [(90, "London", "Headquarter" ), (92, "Muenich", "Support" )] # how many rows to insert cursor.bindarraysize = len(dept_rows) # datatype - lenght of the inserted data cursor.setinputsizes(int, 14, 13) try: # insert the whole record cursor.executemany("insert into dept (DEPTNO, DNAME4,LOC) values (:1, :2,:3)", dept_rows) except cx_Oracle.DatabaseError as e: connection.rollback() print "Oracle Database Error:", e except: print "Unexpected error:", sys.exc_info()[0] raise connection.commit() # Verbindung wieder schliessen cursor.close() connection.close()
Für das Einbinden von PL/SQL müssen die zurück gegeben Werte „gefangen“ werden können.
Procedure in PL/SQL anleegen:
CREATE OR REPLACE PROCEDURE myDate(p_date IN OUT DATE,p_offset NUMBER) AS BEGIN p_date:=sysdate+p_offset; END; /
In Python aufrufen, auf die [] bei callproc achten:
import cx_Oracle connection = cx_Oracle.connect('scott/tiger@10.10.10.1/GPI') cursor = connection.cursor() return_value = cursor.var(cx_Oracle.Date) cursor.callproc('myDate', [return_value,2]) print return_value.getvalue() # return_value = cursor.var(cx_Oracle.STRING) cursor.execute(" BEGIN select sysdate into :1 from dual; END; ", [return_value]) print return_value.getvalue() #close cursor.close() connection.close()
import cx_Oracle import sys # get client library version print "Oracle Client Library Version :: ", cx_Oracle.clientversion() connection = cx_Oracle.connect('scott/tiger@10.10.10.1/GPI') # Version der DB ausgeben print "Oracle Database Version ::", connection.version # Cursor auf die DB oeffenen cursor = connection.cursor() ddl_sql = "create table t7 ( id number(11) not null , texte varchar2(2000))" try: cursor.execute(ddl_sql) except cx_Oracle.DatabaseError as e: print "Oracle Database Error:", e except: print "Unexpected error:", sys.exc_info()[0] raise cursor.close() # Verbindung wieder schliessen connection.close()
see ⇒ http://matplotlib.org
Vorbereitung ⇒ http://aka.ms/vcpython27 herunterladen und installieren (Microsoft Visual C++ Compiler for Python 2.7 )
python -m pip install matplotlib
# -*- coding: iso-8859-1 -*- import cx_Oracle import matplotlib.pyplot as plt import numpy as np # get client library version print "Oracle Client Library Version :: ", cx_Oracle.clientversion() connection = cx_Oracle.connect('scott/tiger@10.10.10.1/GPI') # Version der DB ausgeben print "Oracle Database Version ::", connection.version #Cursor auf die DB öffenen cursor = connection.cursor() #Cursor ausführen cursor.execute('select ename,sal from emp order by empno') #exctract the values to plot plot_values=[] plot_names=[] for ename,sal in cursor.fetchall(): plot_values.append(sal) plot_names.append(ename) ################ Line Plot ########## print plot_values plt.plot(plot_values,'bs') plt.show() ################ Bar diagramm ####### y_pos = np.arange(len(plot_names)) print y_pos error = np.random.rand(len(plot_names)) print error plt.barh(y_pos, plot_values, xerr=0, align='center', alpha=0.8) plt.yticks(y_pos, plot_names) plt.xlabel('Sallery') plt.title('Enough for all?') plt.show() #Verbindung wieder schliessen cursor.close() connection.close()
cx-oracle Dokumentation:
Oracle:
Weitere Seite über das Thema