Dies scheint ein Problem zu sein, wenn jaydebeapi
verwendet wird mit jpype
. Ich kann dies reproduzieren, wenn ich eine Verbindung zu einer Oracle-Datenbank auf die gleiche Weise wie Sie herstelle (in meinem Fall Oracle 11gR2, aber da Sie ojdbc8.jar
verwenden , ich denke, es passiert auch mit anderen Versionen).
Es gibt verschiedene Möglichkeiten, wie Sie dies lösen können:
Ändern Sie Ihre Verbindung
Da der Fehler scheinbar nur bei einer bestimmten Kombination von Paketen auftritt, ist es am sinnvollsten, diese und damit den Fehler ganz zu vermeiden.
-
Alternative 1:Verwenden Sie
jaydebeapi
ohnejpype
:Wie bereits erwähnt, beobachte ich dies nur bei der Verwendung von
jaydebeapi
mitjpype
. In meinem Fall jedochjpype
wird überhaupt nicht benötigt. Ich habe die.jar
Datei lokal und meine Verbindung funktioniert auch ohne sie:import jaydebeapi as jdba import pandas as pd import os db_host = 'db.host.com' db_port = 1521 db_sid = 'YOURSID' jar=os.getcwd()+'/ojdbc6.jar' conn = jdba.connect('oracle.jdbc.driver.OracleDriver', 'jdbc:oracle:thin:@' + db_host + ':' + str(db_port) + ':' + db_sid, {'user': 'USERNAME', 'password': 'PASSWORD'}, jar ) df_jay = pd.read_sql('SELECT * FROM YOURSID.table1', conn) conn.close()
In meinem Fall funktioniert das gut und erstellt die Datenrahmen normal.
-
Alternative 2:Verwenden Sie
cx_Oracle
stattdessen:Das Problem tritt auch nicht auf, wenn ich
cx_Oracle
verwende um sich mit der Oracle-Datenbank zu verbinden:import cx_Oracle import pandas as pd import os db_host = 'db.host.com' db_port = 1521 db_sid = 'YOURSID' dsn_tns = cx_Oracle.makedsn(db_host, db_port, db_sid) cx_conn = cx_Oracle.connect('USERNAME', 'PASSWORD', dsn_tns) df_cxo = pd.read_sql('SELECT * FROM YOURSID.table1', con=cx_conn) cx_conn.close()
Hinweis:Für
cx_Oracle
um zu funktionieren, benötigen Sie den Oracle Instant Client installiert und richtig eingerichtet (siehe z. B. cx_Oracle-Dokumentation für Ubuntu ).
Datenrahmen nachträglich reparieren:
Wenn Sie die obigen Verbindungsalternativen aus irgendeinem Grund nicht verwenden können, können Sie auch Ihren Datenrahmen transformieren.
-
Alternative 3:Join-Tuple-Einträge:
Sie können
''.join()
verwenden um Tupel in Strings umzuwandeln . Sie müssen dies für die Einträge und die Spaltennamen tun.# for all entries that are not None, join the tuples for col in df.select_dtypes(include=['object']).columns: df[col] = df[col].apply(lambda x: ''.join(x) if x is not None else x) # also rename the column headings in the same way df.rename(columns=lambda x: ''.join(x) if x is not None else x, inplace=True)
-
Alternative 4:Spaltentyp ändern:
Durch Ändern des
dtype
einer betroffenen Spalte ausobject
zustring
, werden alle Eingaben ebenfalls konvertiert. Beachten Sie, dass dies unerwünschte Nebenwirkungen haben kann, wie z. Ändern vonNone
-Werte in die Zeichenfolge<N/A>
. Außerdem müssen Sie die Spaltenüberschriften wie oben separat umbenennen.for col in df.select_dtypes(include=['object']).columns: df[col] = df[col].astype('string') # again, rename headings df.rename(columns=lambda x: ''.join(x) if x is not None else x, inplace=True)
All dies sollte mehr oder weniger den gleichen df
ergeben am Ende (abgesehen von den dtypes
und möglicher Ersatz von None
Werte):
+---+---------+---------+---------+
| | COLUMN1 | COLUMN2 | COLUMN3 |
+---+---------+---------+---------+
| 1 | test | test2 | 1 |
+---+---------+---------+---------+
| 2 | foo | bar | 100 |
+---+---------+---------+---------+