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

Matplotlib绘制Oracle SQL查询结果报错:返回141行失败,返回3行正常

解决Matplotlib barh报错:TypeError: unsupported operand type(s) for +: 'int' and 'NoneType'

从你的报错信息和代码来看,这个问题的核心是传递给plt.barh()的数值数组(也就是count_ID)中存在None值——当Matplotlib尝试计算柱子的位置时,无法对整数和None执行加法操作,从而抛出错误。而查询返回3行时能正常运行,是因为这3行的count(ID)结果都是有效的整数,没有混入None。

为什么会出现None值?

有两个关键原因:

  • 查询字符串的语法错误:你代码中的查询用单引号包裹,但内部正则表达式和LTRIM的参数也用了单引号,这会导致Python解析字符串时直接报错(应该会抛出SyntaxError)。如果你的实际代码没修正这个问题,可能会导致查询执行异常,返回的结果中出现None。
  • Oracle查询返回的异常值:当ID字段不匹配正则[0-9]{3,}时,REGEXP_SUBSTR会返回NULL,经过LTRIM后还是NULL。虽然count(ID)理论上应该返回整数,但如果分组的ID是NULL,或者结果处理过程中出现异常,可能会导致count_ID中混入None。

解决方案

1. 修正查询字符串的语法错误

将查询字符串的外层引号改为双引号,或者对内层单引号进行转义,避免Python解析错误:

# 方案1:用双引号包裹外层字符串
query = "select distinct (LTRIM(REGEXP_SUBSTR(ID, '[0-9]{3,}'), '0')) as ReportID, count(ID) from dev_user.RECORD_TABLE group by ID"

# 方案2:转义内层单引号
query = 'select distinct (LTRIM(REGEXP_SUBSTR(ID, \'[0-9]{3,}\'), \'0\')) as ReportID, count(ID) from dev_user.RECORD_TABLE group by ID'

2. 过滤/处理结果中的None值

在遍历查询结果时,检查并处理可能的None值,确保count_ID中都是有效的整数,同时处理ReportID为NULL的情况:

for row in c:
    # 处理ReportID为NULL的情况,替换为默认值
    report_id = row[0] if row[0] is not None else 'Unknown'
    reportid_count.append(report_id)
    # 确保count是整数,避免None
    count = row[1] if row[1] is not None else 0
    count_ID.append(int(count))
    print(f"ReportID: {report_id}, Count: {count}")

3. 可选:用NumPy统一数据类型

Matplotlib对NumPy数组的支持更稳定,你可以将列表转换为NumPy数组,确保类型统一:

reportid_count = np.array(reportid_count)
count_ID = np.array(count_ID, dtype=int)

修正后的完整代码

import os
import cx_Oracle
import matplotlib.pyplot as plt
import numpy as np

dsn_tns = cx_Oracle.makedsn('host', '1521', service_name='S1')
conn = cx_Oracle.connect(user=r'dev_user', password='Welcome', dsn=dsn_tns)

reportid_count = []
count_ID = []

c = conn.cursor()
# 修正后的查询字符串(用双引号避免单引号冲突)
query = "select distinct (LTRIM(REGEXP_SUBSTR(ID, '[0-9]{3,}'), '0')) as ReportID, count(ID) from dev_user.RECORD_TABLE group by ID"
c.execute(query)

# 遍历结果并处理None值
for row in c:
    report_id = row[0] if row[0] is not None else 'Unknown'
    reportid_count.append(report_id)
    count = row[1] if row[1] is not None else 0
    count_ID.append(int(count))
    print(report_id)
    print(count)

fig = plt.figure(figsize=(13.5, 5))
# 绘制水平柱状图
plt.barh(reportid_count, count_ID)

# 添加数值标签
for i, v in enumerate(count_ID):
    plt.text(v, i, str(v), color='blue', fontweight='bold')

plt.title('Report_Details')
plt.xlabel('Report Count')
plt.ylabel("Report ID's")

# 修正网络路径格式并保存图片
path = r"\\dev_server.com\View\Foldert\uidDocuments\Store_Img"
os.chdir(path)
plt.savefig('squares.png')
plt.show()

conn.close()

额外注意事项

  • 你的网络路径字符串需要以\\开头(修正为r"\\dev_server.com\View\Foldert\uidDocuments\Store_Img")才能正确访问。
  • 原代码最后一行conn.close())多了一个右括号,已经在修正后的代码中去掉了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 14:27:39