To se zdá být problém při použití jaydebeapi
pomocí jpype
. Mohu to reprodukovat při připojení k databázi Oracle stejným způsobem jako vy (v mém případě Oracle 11gR2, ale protože používáte ojdbc8.jar
, předpokládám, že se to stává i u jiných verzí).
Existují různé způsoby, jak to můžete vyřešit:
Změňte připojení
Protože se zdá, že k chybě dochází pouze v určité kombinaci balíčků, nejrozumnější věcí, kterou můžete udělat, je pokusit se vyhnout se těmto chybám a tím i chybě.
-
Alternativa 1:Použijte
jaydebeapi
bezjpype
:Jak bylo uvedeno, pozoruji to pouze při použití
jaydebeapi
pomocíjpype
. Nicméně v mém případějpype
není vůbec potřeba. Mám.jar
soubor lokálně a moje připojení bez něj funguje dobře: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()
V mém případě to funguje dobře a vytváří datové rámce normálně.
-
Alternativa 2:Použijte
cx_Oracle
místo toho:Problém také nenastane, pokud použiji
cx_Oracle
pro připojení k databázi Oracle: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()
Poznámka:Pro
cx_Oracle
abyste mohli pracovat, musíte mít Oracle Instant Client nainstalováno a správně nastaveno (viz např. dokumentace cx_Oracle pro Ubuntu ).
Následně opravit datový rámec:
Pokud z nějakého důvodu nemůžete použít výše uvedené alternativy připojení, můžete také transformovat svůj datový rámec.
-
Alternativa 3:spojení n-ticových záznamů:
Můžete použít
''.join()
jak převést n-tice na řetězce . Musíte to udělat pro položky a názvy sloupců.# 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)
-
Alternativa 4:změna dtype sloupců:
Změnou
dtype
ovlivněného sloupce zobject
nastring
, budou také převedeny všechny položky. Upozorňujeme, že to může mít nežádoucí vedlejší účinky, jako např. změnaNone
hodnoty do řetězce<N/A>
. Také budete muset samostatně přejmenovat záhlaví sloupců, jak je uvedeno výše.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)
Všechny by měly přinést víceméně stejné df
nakonec (kromě dtypes
a možné nahrazení None
hodnoty):
+---+---------+---------+---------+
| | COLUMN1 | COLUMN2 | COLUMN3 |
+---+---------+---------+---------+
| 1 | test | test2 | 1 |
+---+---------+---------+---------+
| 2 | foo | bar | 100 |
+---+---------+---------+---------+