Đây có vẻ là sự cố khi sử dụng jaydebeapi
với jpype
. Tôi có thể tái tạo điều này khi kết nối với Oracle db theo cách giống như cách bạn làm (trong trường hợp của tôi là Oracle 11gR2, nhưng vì bạn đang sử dụng ojdbc8.jar
, Tôi đoán nó cũng xảy ra với các phiên bản khác).
Có nhiều cách khác nhau mà bạn có thể giải quyết vấn đề này:
Thay đổi kết nối của bạn
Vì lỗi dường như chỉ xảy ra trong một tổ hợp các gói cụ thể, điều hợp lý nhất cần làm là thử và tránh những điều này và do đó lỗi hoàn toàn.
-
Cách 1:Sử dụng
jaydebeapi
không cójpype
:Như đã lưu ý, tôi chỉ quan sát thấy điều này khi sử dụng
jaydebeapi
vớijpype
. Tuy nhiên, trong trường hợp của tôi,jpype
là không cần thiết ở tất cả. Tôi có.jar
tệp cục bộ và kết nối của tôi hoạt động tốt mà không có nó: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()
Trong trường hợp của tôi, điều này hoạt động tốt và tạo khung dữ liệu bình thường.
-
Phương án 2:Sử dụng
cx_Oracle
thay vào đó:Sự cố cũng không xảy ra nếu tôi sử dụng
cx_Oracle
để kết nối với 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()
Lưu ý:Đối với
cx_Oracle
để hoạt động, bạn phải có Ứng dụng khách tức thì của Oracle được cài đặt và thiết lập đúng cách (xem ví dụ: cx_Oracle tài liệu dành cho Ubuntu ).
Sửa khung dữ liệu sau thực tế:
Nếu vì lý do nào đó, bạn không thể sử dụng các lựa chọn thay thế kết nối ở trên, bạn cũng có thể chuyển đổi khung dữ liệu của mình.
-
Phương án 3:tham gia các mục nhập tuple:
Bạn có thể sử dụng
''.join()
để chuyển đổi bộ giá trị thành chuỗi . Bạn cần thực hiện việc này đối với các mục nhập và tên cột.# 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)
-
Phương án 4:thay đổi loại cột:
Bằng cách thay đổi
dtype
của một cột bị ảnh hưởng từobject
thànhstring
, tất cả các mục nhập cũng sẽ được chuyển đổi. Lưu ý rằng điều này có thể có các tác dụng phụ không mong muốn, như v.d. thay đổiNone
giá trị cho chuỗi<N/A>
. Ngoài ra, bạn sẽ phải đổi tên riêng các tiêu đề cột, như ở trên.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)
Tất cả những thứ này ít nhiều phải mang lại cùng một df
cuối cùng (ngoài dtypes
và có thể thay thế None
giá trị):
+---+---------+---------+---------+
| | COLUMN1 | COLUMN2 | COLUMN3 |
+---+---------+---------+---------+
| 1 | test | test2 | 1 |
+---+---------+---------+---------+
| 2 | foo | bar | 100 |
+---+---------+---------+---------+