Esto parece ser un problema cuando se usa jaydebeapi con jpype . Puedo reproducir esto cuando me conecto a una base de datos Oracle de la misma manera que lo haces tú (en mi caso, Oracle 11gR2, pero como estás usando ojdbc8.jar , supongo que también pasa con otras versiones).
Hay diferentes formas de resolver esto:
Cambia tu conexión
Dado que el error solo parece ocurrir en una combinación específica de paquetes, lo más sensato es tratar de evitarlos y, por lo tanto, el error por completo.
-
Alternativa 1:Usar
jaydebeapisinjpype:Como se señaló, solo observo esto cuando uso
jaydebeapiconjpype. Sin embargo, en mi caso,jpypeno es necesario en absoluto. Tengo el.jararchivo localmente y mi conexión funciona bien sin él: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()En mi caso, esto funciona bien y crea los marcos de datos normalmente.
-
Alternativa 2:Usar
cx_Oracleen cambio:El problema tampoco ocurre si uso
cx_Oraclepara conectarse a la base de datos de 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()Nota:para
cx_Oraclepara trabajar tienes que tener el Oracle Instant Client instalado y configurado correctamente (consulte, por ejemplo, cx_Documentación de Oracle para Ubuntu ).
Corregir marco de datos después del hecho:
Si por algún motivo no puede utilizar las alternativas de conexión anteriores, también puede transformar su marco de datos.
-
Alternativa 3:unir entradas de tupla:
Puedes usar
''.join()para convertir tuplas en cadenas . Debe hacer esto para las entradas y los nombres de las columnas.# 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:cambiar el tipo de columnas:
Cambiando el
dtypede una columna afectada deobjectastring, todas las entradas también se convertirán. Tenga en cuenta que esto puede tener efectos secundarios no deseados, como p. cambiandoNonevalores a la cadena<N/A>. Además, tendrá que cambiar el nombre de los encabezados de las columnas por separado, como se indicó anteriormente.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)
Todos estos deberían producir más o menos el mismo df al final (aparte de los dtypes y posible reemplazo de None valores):
+---+---------+---------+---------+
| | COLUMN1 | COLUMN2 | COLUMN3 |
+---+---------+---------+---------+
| 1 | test | test2 | 1 |
+---+---------+---------+---------+
| 2 | foo | bar | 100 |
+---+---------+---------+---------+