Python调用MySQL脚本时ProgrammingError异常捕获失效问题咨询
哦,我明白你的问题了!你遇到的核心问题不是导入ProgrammingError的问题,而是你用get_ipython().system()调用脚本的方式,导致子进程的异常根本传不到当前脚本的try-except块里。
当你用get_ipython().system()或者!ipython运行另一个脚本时,其实是启动了一个完全独立的子进程来执行那个脚本。子进程里抛出的任何异常,都会在子进程内部处理(或者直接崩溃输出错误),不会传递到父进程(也就是你当前运行这个try-except的IPython会话)。所以你的try-except相当于“守错了地方”,根本抓不到子进程的错误。
下面给你两种可行的解决方案:
方案1:直接调用脚本里的函数(推荐)
这是最干净的做法,把填充逻辑封装成函数,然后在当前脚本里导入调用,这样异常就能被正常捕获:
- 先修改
/path/to/pythonScript.py,把填充代码封装成函数:
# /path/to/pythonScript.py import mysql.connector from mysql.connector.errors import ProgrammingError def populate_database(): # 这里放你原来的数据库填充逻辑,包括防重复的代码 # 比如连接数据库、执行插入操作等 pass
- 然后在当前脚本里这样调用:
import mysql.connector from mysql.connector.errors import ProgrammingError # 注意:如果pythonScript.py不在当前Python路径里,需要先把路径加上 import sys sys.path.append("/path/to") # 脚本所在目录的路径 from pythonScript import populate_database try: populate_database() except ProgrammingError as e: # 可以更精准判断是不是重复键的错误 if "1061 (42000): Duplicate key name 'unique_index'" in str(e): print("提示尝试插入重复条目的警告信息") else: # 其他ProgrammingError的情况,比如SQL语法错误,还是要抛出 raise
方案2:用subprocess捕获子进程错误(如果不能修改填充脚本)
如果因为某些原因无法修改填充脚本,必须用子进程方式调用,那可以用subprocess模块来捕获子进程的输出和返回状态:
import subprocess import sys try: # 用sys.executable保证调用的是当前Python环境的解释器 result = subprocess.run( [sys.executable, "/path/to/pythonScript.py"], capture_output=True, text=True, check=True # 子进程返回非0时抛出CalledProcessError ) except subprocess.CalledProcessError as e: # 检查stderr里的错误信息,判断是不是重复键的问题 if "Duplicate key name 'unique_index'" in e.stderr: print("提示尝试插入重复条目的警告信息") else: # 其他错误,打印详细信息后重新抛出 print(f"脚本执行出错: {e.stderr}") raise
总结一下:你原来的ProgrammingError导入是没问题的,问题完全出在调用脚本的方式上。子进程的异常和父进程是隔离的,所以用get_ipython().system()根本没法捕获到子进程里的MySQL异常。上面两种方案里,方案1是最推荐的,因为它让代码更模块化,也更容易处理异常。
内容的提问来源于stack exchange,提问作者BCArg
相关产品推荐
相关产品推荐

