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
相关产品推荐
相关产品推荐

