Dit lijkt een probleem te zijn bij het gebruik van jaydebeapi
met jpype
. Ik kan dit reproduceren wanneer ik verbinding maak met een Oracle db op dezelfde manier als jij (in mijn geval Oracle 11gR2, maar aangezien je ojdbc8.jar
gebruikt , ik denk dat het ook gebeurt met andere versies).
Er zijn verschillende manieren om dit op te lossen:
Wijzig uw verbinding
Aangezien de fout alleen lijkt op te treden in een specifieke combinatie van pakketten, is het het meest verstandig om te proberen deze en dus de fout helemaal te vermijden.
-
Alternatief 1:gebruik
jaydebeapi
zonderjpype
:Zoals opgemerkt, observeer ik dit alleen bij het gebruik van
jaydebeapi
metjpype
. In mijn geval echterjpype
is helemaal niet nodig. Ik heb de.jar
bestand lokaal en mijn verbinding werkt prima zonder: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 mijn geval werkt dit prima en worden de dataframes normaal gemaakt.
-
Alternatief 2:gebruik
cx_Oracle
in plaats daarvan:Het probleem doet zich ook niet voor als ik
cx_Oracle
gebruik om verbinding te maken met de Oracle db: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()
Opmerking:voor
cx_Oracle
om te werken moet je de Oracle Instant Client hebben geïnstalleerd en correct ingesteld (zie bijv. cx_Oracle documentatie voor Ubuntu ).
Dataframe achteraf repareren:
Als u om de een of andere reden de bovenstaande verbindingsalternatieven niet kunt gebruiken, kunt u ook uw dataframe transformeren.
-
Alternatief 3:voeg tuple-items toe:
U kunt
''.join()
. gebruiken om tuples te converteren naar strings . U moet dit doen voor de vermeldingen en de kolomnamen.# 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)
-
Alternatief 4:dtype kolommen wijzigen:
Door het
dtype
. te wijzigen van een getroffen kolom uitobject
naarstring
, worden alle vermeldingen ook geconverteerd. Houd er rekening mee dat dit ongewenste bijwerkingen kan hebben, zoals b.v.None
wijzigen waarden naar de tekenreeks<N/A>
. U zult ook de kolomkoppen afzonderlijk moeten hernoemen, zoals hierboven.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)
Al deze zouden min of meer dezelfde df
. moeten opleveren uiteindelijk (afgezien van de dtypes
en mogelijke vervanging van None
waarden):
+---+---------+---------+---------+
| | COLUMN1 | COLUMN2 | COLUMN3 |
+---+---------+---------+---------+
| 1 | test | test2 | 1 |
+---+---------+---------+---------+
| 2 | foo | bar | 100 |
+---+---------+---------+---------+