我在稍微不同的环境中遇到了同样的问题。我需要查询一个 +27000 行的表,结果发现 cx_Oracle 会在一段时间后切断与数据库的连接。
当与数据库的连接打开时,您可以使用 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 行表,但它在其他一切都没有的情况下工作。
如果有人知道更好的方法,那对我也有帮助。