You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

cx_Oracle相关Python代码实现问题:类初始化时__init__方法逻辑报错

可能的报错原因
  • 缩进错误导致死循环:你代码中的i += 1被放在了while循环的外部,循环体内i的值永远为0,只要procedureName列表长度大于0就会进入无限循环,最终会因为重复调用存储过程耗尽数据库连接资源、或者内存溢出触发报错。你单独运行逻辑时大概率缩进是正确的,挪到__init__方法中时不小心写错了缩进层级。
  • 存储过程参数匹配错误:代码中根据存储过程名判断传入参数的数量,如果从all_procedures表查询到的存储过程名存在大小写、拼写差异,导致判断逻辑不生效,就会出现给不需要accountCode的存储过程多传参数、或者给需要的存储过程漏传参数的情况,触发cx_Oracle调用报错。单独运行逻辑时你大概率是硬编码指定了存储过程名,不会触发这个判断错误。
  • 连接提前关闭导致游标失效:__init__方法执行完成后会立刻关闭游标和数据库连接,部分版本的cx_Oracle中存储过程返回的游标绑定了数据库会话,你转DataFrame时如果还没完全拉取完所有数据,连接已经被关闭,就会抛出游标无效、会话已终止的报错。单独运行逻辑时你可能把关闭连接的动作放在了所有DataFrame转换完成之后,不会触发这个问题。
  • 账号权限不足:单独跑脚本时你可能用的是个人Oracle账号,有对应存储过程的执行权限,类初始化时你硬编码了CORP-SVC-IFT账号,这个账号可能缺少部分存储过程的执行权限、或者缺少all_procedures系统表的查询权限,导致查询结果为空、或者调用存储过程触发权限不足报错。
修复参考代码
from pandas.core.frame import DataFrame
import cx_Oracle
import pandas as pd
import sys

class IFTDataCore:
    def __init__(self, accountCode):
        all_Procedures = []
        dns_tns = cx_Oracle.makedsn("gbhenora06vd.corp.amvescap.net", "1525", "INVU")
        db = None
        cursor = None
        try:
            db = cx_Oracle.connect("CORP-SVC-IFT", "C$Rp$vc1ftUat", dns_tns)
            cursor = db.cursor()
            cursor.execute("select procedure_name from all_procedures where object_name = 'PK_IVZ_IFT_EXTRACT' ")
            rows = cursor.fetchall()
            procedureName = [f'PK_IVZ_IFT_EXTRACT.{row[0]}' for row in rows]
            l_cur = cursor.var(cx_Oracle.CURSOR)
            # 替换while为for循环,避免缩进错误
            for proc_name in procedureName:
                if proc_name == 'PK_IVZ_IFT_EXTRACT.SP_IVZ_IFT_EXTRACT_ACCOUNTS':   
                    ret_cursor = cursor.callproc(proc_name, (l_cur,))
                else:
                    ret_cursor = cursor.callproc(proc_name, (l_cur, accountCode))
                # 先拉取全部游标数据再转DataFrame,避免连接关闭后数据丢失
                cur_rows = list(ret_cursor[0])
                dfx = pd.DataFrame(cur_rows)  
                all_Procedures.append(dfx)
            self.all_Procedures = all_Procedures
        except Exception as e:
            # 打印具体错误信息方便定位
            print(f"执行出错: {str(e)}")
            raise
        finally:
            if cursor:
                cursor.close()
            if db:
                db.close()

    @property
    def getallProcedures(self):
        return self.all_Procedures

if __name__ == '__main__':
    all_Proc = IFTDataCore('TOUHI')
    Procedures = all_Proc.getallProcedures()
    print(Procedures[0])

内容的提问来源于stack exchange,提问作者user1547637

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.14 06:51:02