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

cx_Oracle组件outconverter处理Number类型None值失效问题求助

问题:cx_Oracle中Number字段None值未触发outconverter转换的解决方法

需求:通过cx_Oracle从数据库获取数据,当Number字段值为None时需转换为-1。尝试使用Variable的outconverter属性实现,但发现None值未触发转换。

示例代码:

import cx_Oracle

with cx_Oracle.connect("omrscpif" ,"omrscpif", 'ammiceng') as connect:
    def OutConverter(value):
        if value is None:
            return ''
        return value

    def NumberOutConverter(value):
        if value is None:
            return -1
        return value


    def OutputTypeHandler(cursor, name, defaultType, size, precision, scale):
        if defaultType in (cx_Oracle.STRING, cx_Oracle.FIXED_CHAR):
            return cursor.var(str, size, cursor.arraysize, outconverter=OutConverter)

        if defaultType == cx_Oracle.DB_TYPE_NUMBER:
            return cursor.var(cx_Oracle.DB_TYPE_NUMBER, size, cursor.arraysize, outconverter=NumberOutConverter)

    # Finally, we will assign the defination to the outputtypehandler of the connect.
    connect.outputtypehandler = OutputTypeHandler

    with connect.cursor() as cursor:
        cursor.execute("select fordertypevalue, forderqtyfuturecommitted, fbackorderqty from so_send where ftrnflg = 'N'")
        result = cursor.fetchall()
        print(result)

执行结果:

[(None, None, 1.0)]

解决方案

cx_Oracle的outconverter在字段值为NULL时不会被触发,驱动处理NULL值时会直接返回None,跳过转换器。可以改用cursor.rowfactory来处理每一行数据,对每个字段值做针对性转换:

修改后的代码:

import cx_Oracle

def process_row(cursor, row):
    processed = []
    for idx, value in enumerate(row):
        # 获取当前字段的类型
        col_type = cursor.description[idx][1]
        if value is None:
            if col_type in (cx_Oracle.STRING, cx_Oracle.FIXED_CHAR):
                processed.append('')
            elif col_type == cx_Oracle.DB_TYPE_NUMBER:
                processed.append(-1)
            else:
                processed.append(value)
        else:
            processed.append(value)
    return tuple(processed)

with cx_Oracle.connect("omrscpif", "omrscpif", "ammiceng") as connect:
    with connect.cursor() as cursor:
        # 绑定行处理函数
        cursor.rowfactory = process_row
        cursor.execute("select fordertypevalue, forderqtyfuturecommitted, fbackorderqty from so_send where ftrnflg = 'N'")
        result = cursor.fetchall()
        print(result)

核心说明:

  1. process_row函数遍历每行的每个字段,通过cursor.description获取字段类型
  2. 判断值是否为None,针对字符串、Number类型分别做转换,其他类型保持原样
  3. 处理后的行转为元组返回,保持原结果的格式一致性

执行后结果会变为:

[('', -1, 1.0)]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 17:35:24