在略有不同的情况下,我遇到了同样的问题。我需要查询一个 +27000 行的表,结果发现 cx_Oracle 会在一段时间后切断与数据库的连接。
当与 db 的连接打开时,您可以使用 cx_Oracle.Lob 对象的 read() 方法将其转换为字符串。但是,如果查询带来的表太大,它将无法工作,因为连接将在某个时候停止,并且当您想从查询中读取结果时,您将在 cx_Oracle 对象上出现错误。
我尝试了很多事情,比如设置 connection.callTimeout = 0 (根据文档,这意味着它会无限期地等待),使用 fetchall() 然后将结果放在数据帧或 numpy 数组中,但我永远无法读取 cx_Oracle.Lob 对象.
如果我尝试使用 pandas.DataFrame.read_sql(query, connection) 运行查询,数据框将包含 cx_Oracle.Lob 对象,连接关闭,使它们无用。(同样,这只发生在桌子很大的情况下)
最后,我找到了一种通过查询并立即创建 csv 文件来解决此问题的方法,即使我知道这并不理想。
def csv_from_sql(sql: str, path: str="dataframe.csv") -> bool:
try:
with cx_Oracle.connect(config.username, config.password, config.database, encoding=config.encoding) as connection:
connection.callTimeout = 0
data = pd.read_sql(sql, con=connection)
data.to_csv(path)
print("FILE CREATED")
except cx_Oracle.Error as error:
print(error)
return False
finally:
print("PROCESS ENDED\n")
return True
def make_query(sql: str, path: str="dataframe.csv") -> pd.DataFrame:
if csv_from_sql(sql, path):
dataframe = pd.read_csv("dataframe.csv")
return dataframe
return pd.DataFrame()
这需要很长时间(大约 4 到 5 分钟)才能带来我的 +27000 行表,但是当其他一切都没有时,它就起作用了。
如果有人知道更好的方法,那对我也有帮助。