Python执行SQL文件时报文件不存在错误的问题排查
问题排查方向与解决方案
首先纠正测试误区
你用来验证路径的os.listdir()用法本身就是错的:这个函数的入参必须是目录路径,传入完整文件路径无论文件是否存在都会抛出FileNotFoundError,这个测试结果没有参考价值,不要被误导。正确的文件/路径存在性校验要用os.path.exists()。
路径问题排查步骤
按从上层到下层的顺序逐层校验路径,定位出错节点:
- 先导入os模块,从用户目录开始逐层判断存在性:
import os # 逐层执行,看哪一步返回False print(os.path.exists(r'C:\Users\gsumarlin')) print(os.path.exists(r'C:\Users\gsumarlin\Documents')) print(os.path.exists(r'C:\Users\gsumarlin\Documents\dumps')) print(os.path.exists(r'C:\Users\gsumarlin\Documents\dumps\Dump20220428')) print(os.path.exists(r'C:\Users\gsumarlin\Documents\dumps\Dump20220428\Query_for_testingintern.sql'))
- 定位到返回False的路径层级后,对应排查常见问题:
- 如果是用户目录层报错:说明你当前登录系统的账号名不是
gsumarlin,很多企业域账号会在用户目录后加域名后缀,比如gsumarlin.micron,可以先执行print(os.path.expanduser('~'))查看当前账号的真实用户目录路径,再拼接后续路径 - 如果是中间文件夹层报错:检查文件夹名拼写,注意有没有隐藏的空格、大小写差异、版本后缀(比如实际文件夹名是
Dump20220428_bak这类) - 如果是最终文件层报错:大概率是文件名拼写错误,或者Windows默认隐藏已知文件扩展名导致的后缀名错误——比如文件实际叫
Query_for_testingintern.sql.txt,但资源管理器里隐藏了.txt后缀,你看到的文件名不完整。可以在对应文件夹下执行print(os.listdir(r'C:\Users\gsumarlin\Documents\dumps\Dump20220428'))打印目录下所有真实文件名,复制准确的文件名使用。
- 如果是用户目录层报错:说明你当前登录系统的账号名不是
脚本本身的隐患修复
你的现有脚本除了路径问题,还有几个容易出问题的点,建议一并修改:
- 不要手动调用
open()/close()操作文件,用with上下文管理器自动处理文件关闭,避免句柄泄漏,同时指定文件编码避免乱码 - 不要用裸
except: pass吞掉所有异常,会把SQL执行错误、权限错误等所有报错都隐藏,出问题完全无法定位 - 不要在函数内直接调用全局的cursor变量,耦合度太高,建议作为参数传入
- 参考修正后的代码:
import mysql.connector import os def executeScriptsFromFile(filename, cursor): # 先校验文件存在 if not os.path.exists(filename): raise FileNotFoundError(f"文件不存在: {filename}") # 上下文管理器处理文件 with open(filename, 'r', encoding='utf8') as fd: sqlFile = fd.read() sqlCommands = sqlFile.split(';') for command in sqlCommands: command = command.strip() if not command: continue try: cursor.execute(command) except Exception as e: # 打印具体错误信息,不要吞错 print(f"SQL执行失败: {command}\n错误信息: {str(e)}") if __name__ == "__main__": cnx = mysql.connector.connect( user='skynetadmin', password='Skynetadmin1', host='silmysskytest01.sing.micron.com', database='skynet_msa' ) cursor = cnx.cursor() # 自动获取当前用户目录拼接路径,避免硬编码用户名错误 sql_path = os.path.join( os.path.expanduser('~'), 'Documents', 'dumps', 'Dump20220428', 'Query_for_testingintern.sql' ) executeScriptsFromFile(sql_path, cursor) cnx.commit() cursor.close() cnx.close()
内容的提问来源于stack exchange,提问作者Gracella Q Sumarlin
相关产品推荐
相关产品推荐

