Cela semble être un problème lors de l'utilisation de jaydebeapi
avec jpype
. Je peux reproduire cela lors de la connexion à une base de données Oracle de la même manière que vous (dans mon cas Oracle 11gR2, mais puisque vous utilisez ojdbc8.jar
, je suppose que cela arrive aussi avec d'autres versions).
Vous pouvez résoudre ce problème de différentes manières :
Modifier votre connexion
Étant donné que l'erreur ne semble se produire que dans une combinaison spécifique de packages, la chose la plus sensée à faire est d'essayer d'éviter ceux-ci et donc l'erreur.
-
Alternative 1 :Utiliser
jaydebeapi
sansjpype
:Comme indiqué, je n'observe cela que lors de l'utilisation de
jaydebeapi
avecjpype
. Cependant, dans mon cas,jpype
n'est pas du tout nécessaire. J'ai le.jar
fichier local et ma connexion fonctionne bien sans :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()
Dans mon cas, cela fonctionne bien et crée les dataframes normalement.
-
Alternative 2 :Utiliser
cx_Oracle
à la place :Le problème ne se produit pas non plus si j'utilise
cx_Oracle
pour se connecter à la base de données 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()
Remarque :Pour
cx_Oracle
pour travailler, vous devez avoir le Oracle Instant Client installé et correctement configuré (voir par exemple documentation cx_Oracle pour Ubuntu ).
Corrigez la trame de données après coup :
Si pour une raison quelconque, vous ne pouvez pas utiliser les alternatives de connexion ci-dessus, vous pouvez également transformer votre dataframe.
-
Alternative 3 :joindre les entrées de tuple :
Vous pouvez utiliser
''.join()
pour convertir les tuples en chaînes . Vous devez le faire pour les entrées et les noms de colonne.# 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 :modifier le type de colonnes :
En changeant le
dtype
d'une colonne affectée deobject
àstring
, toutes les entrées seront également converties. Notez que cela peut avoir des effets secondaires indésirables, comme par ex. changerNone
valeurs à la chaîne<N/A>
. De plus, vous devrez renommer les en-têtes de colonne séparément, comme ci-dessus.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)
Tous ces éléments devraient donner plus ou moins le même df
au final (à part les dtypes
et remplacement éventuel de None
valeurs):
+---+---------+---------+---------+
| | COLUMN1 | COLUMN2 | COLUMN3 |
+---+---------+---------+---------+
| 1 | test | test2 | 1 |
+---+---------+---------+---------+
| 2 | foo | bar | 100 |
+---+---------+---------+---------+