如何通过Python将Oracle update查询结果写入指定路径的CSV文件
代码问题原因与修改方案
核心问题说明
你当前的代码存在3个直接导致无法写入数据的问题:
UPDATE是Oracle的DML操作,执行后只会返回受影响行数,不会返回任何结果集,你无法直接从执行UPDATE的cursor中拿到可写入CSV的行数据,必须在UPDATE执行完成后,新增对应的SELECT查询来获取更新后的目标数据。- 你创建CSV写入对象时,错误传入了已经关闭的第一个文件句柄
f,而非新打开的f1,导致写入操作根本没有指向你创建的res2.csv文件。 - 你在UPDATE已经执行并提交后,重复调用
cursor.execute(SQL1),此时符合dname = 'SALES'条件的数据已经被修改,第二次执行不会有任何记录被匹配到,属于无效操作。
修正后的代码示例
import cx_Oracle import csv import pandas as pd # 建立数据库连接 db = cx_Oracle.connect ('user/pass@host:port/service_name') cursor = db.cursor() # 原SELECT导出逻辑不变 SQL = "select e.empno as employee_number,e.ename as employee_name ,e.sal as salary,d.deptno as department_number,d.dname as department_name from emp e,dept d where e.deptno=d.deptno order by e.empno,e.ename,e.sal,d.deptno,d.dname" print(SQL) with open("e:\\OT_DIR\\employeedetails1.csv", "w") as f: writer = csv.writer(f, lineterminator="\n", quoting=csv.QUOTE_NONNUMERIC) cursor.execute(SQL) # 写入表头 col_names = [row[0] for row in cursor.description] writer.writerow(col_names) # 写入数据行 for row in cursor: writer.writerow(row) # 读取CSV的逻辑不变 df = pd.read_csv("E:\\OT_DIR\\employeedetails1.csv") df.to_csv("employeedetails1.csv", index=False) print(df) # 执行UPDATE操作 SQL1 = '''update dept set dname='xyz' where dname = 'SALES'and exists (select distinct 1 from emp,dept where emp.deptno= dept.deptno )''' cursor.execute(SQL1) db.commit() print(cursor.rowcount, "record(s) affected") # -------------------- 新增/修改部分开始 -------------------- # 1. 新增SELECT语句,查询更新后你需要导出的数据,这里以查询更新后的dept表为例 # 你也可以根据需求写其他查询,比如重新执行最开始的关联SQL获取更新后的全量员工部门数据 select_updated_sql = "select deptno, dname, loc from dept where dname = 'xyz'" # 2. 执行查询获取结果集 cursor.execute(select_updated_sql) # 3. 修正文件句柄错误,用新打开的f1创建写入对象 with open("e:\\OT_DIR\\res2.csv", "w") as f1: writer = csv.writer(f1, lineterminator="\n", quoting=csv.QUOTE_NONNUMERIC) # 写入表头 updated_col_names = [row[0] for row in cursor.description] writer.writerow(updated_col_names) # 写入更新后的行数据 for row in cursor: writer.writerow(row) # -------------------- 新增/修改部分结束 -------------------- # 关闭资源 cursor.close() db.close()
补充说明
如果你需要导出本次UPDATE涉及的所有原始/更新后数据,可以在UPDATE执行前先把符合条件的行查出来存到变量里,UPDATE完成后再写入CSV,避免更新后无法匹配到原始数据。
另外推荐统一使用with上下文管理器管理文件打开关闭,无需手动调用close(),避免出现资源泄漏或者句柄引用错误的问题。
内容的提问来源于stack exchange,提问作者Chinmayee Nayak
相关产品推荐
相关产品推荐

