使用Python将Excel导入Oracle表时遇TypeError错误求助
解决cx_Oracle插入时的TypeError: expecting string or bytes object问题
问题分析
你遇到的错误根源是Excel导入的DataFrame中存在非字符串类型数据(比如数字、NaN空值),而Oracle表的KRN和KRN_TIN列定义为VARCHAR2,cx_Oracle要求插入该类型的必须是字符串或字节对象,类型不匹配就会触发这个报错。
解决方案
1. 统一转换数据类型并处理空值
在生成插入用的tuple列表前,先把DataFrame中的目标列强制转为字符串类型,同时将NaN替换为空字符串:
krn = pd.read_excel("KRN TIN.xlsx", engine='openpyxl', sheet_name='Sheet1', parse_dates=False) tin = krn.loc[:,['APPRAISER','TIN']] tin = tin.drop_duplicates() # 转换为字符串并处理空值 tin['APPRAISER'] = tin['APPRAISER'].astype(str).replace('nan', '') tin['TIN'] = tin['TIN'].astype(str).replace('nan', '') # 生成符合要求的tuple列表 rows = [tuple(row) for row in tin.itertuples(index=False, name=None)]
2. 修正代码中的其他问题
- 删掉提前执行的
conn2.close()(此时连接还未创建,会引发额外报错); - 保留正确的
create_table定义,删除重复的错误语句; - 确保插入语句的占位符与tuple元素顺序一致(cx_Oracle支持从0或1开始的索引,保持统一即可)。
修正后的完整代码:
import pandas as pd import cx_Oracle # 读取并预处理数据 krn = pd.read_excel("KRN TIN.xlsx", engine='openpyxl', sheet_name='Sheet1', parse_dates=False) tin = krn.loc[:,['APPRAISER','TIN']].drop_duplicates() # 转换类型+处理空值 tin['APPRAISER'] = tin['APPRAISER'].astype(str).replace('nan', '') tin['TIN'] = tin['TIN'].astype(str).replace('nan', '') rows = [tuple(row) for row in tin.itertuples(index=False, name=None)] # 数据库操作 conn2 = cx_Oracle.connect(user=xx, password=x_pwd, dsn=dsn_tns2, encoding="UTF-8") cur = conn2.cursor() # 创建表(Oracle 12c+可加IF NOT EXISTS避免重复创建报错) create_table = '''CREATE TABLE TEMP_KRN (KRN VARCHAR2(255), KRN_TIN VARCHAR2(255))''' cur.execute(create_table) cur.execute('grant select on KSG_LOSS_RPTG_SB.TEMP_KRN to PUBLIC') # 插入数据,占位符与tuple顺序对应 cur.executemany('''INSERT INTO TEMP_KRN(KRN, KRN_TIN) VALUES (:1, :2)''', rows) conn2.commit() # 关闭资源 cur.close() conn2.close()
3. 额外检查点
- 确认Excel中
TIN列是否有带前导零的数字,转换为字符串后能保留格式; - 如果表已存在,可先执行
DROP TABLE IF EXISTS TEMP_KRN(Oracle 12c+支持),避免创建报错。
内容的提问来源于stack exchange,提问作者mluanastevens
相关产品推荐
相关产品推荐

