SQLAlchemy上传DataFrame至AWS RDS MySQL时如何打印数据截断等警告
问题成因
- 当前代码无法展示截断类警告的核心原因有三点:
- MySQL返回的字段截断、数值越界类提示默认属于Warning级别,不会触发Python层面的异常抛出,现有try-except块只能捕获Error级别的错误,根本接不到这类提示
- mysql.connector默认关闭了服务端警告拉取逻辑,这类SQL层的警告会被客户端静默吞掉,不会推送到Python的日志或警告流中
to_sql方法本身默认不会校验写入过程的字段截断情况,只要SQL执行没有触发硬错误就会正常走完流程
具体改造步骤
- 全局开启Python警告输出:在代码开头配置警告过滤器,强制所有级别的警告都打印,不做静默过滤
- 创建数据库连接时显式配置参数:打开服务端警告拉取开关,同时设置不把警告转为异常,避免遇到警告就中断整个写入流程
- 写入完成后主动查询当前会话的警告列表:兜底拉取所有服务端返回的截断、转换类提示,避免依赖客户端的警告上报逻辑漏采
- 移除冗余的手动连接关闭逻辑:with上下文管理器会自动完成连接的回收释放,手动调用close反而容易触发重复关闭的异常
改造后可直接运行的代码
import warnings from sqlalchemy import create_engine from sqlalchemy.pool import NullPool # 强制所有警告全量输出,不做静默过滤 warnings.simplefilter("always", category=Warning) def load_data(translog, input_size): try: print("Creating connection") engine = create_engine( "mysql+mysqlconnector://<username>:<pwd>@XXXXXXX.rds.amazonaws.com/XXXX", poolclass=NullPool, connect_args={ # 主动拉取MySQL服务端返回的所有警告,包含数据截断类提示 "get_warnings": True, # 不把警告转为异常抛出,保证写入流程不中断 "raise_on_warnings": False } ) with engine.connect() as connection: translog.to_sql( con=connection, name='transtry', if_exists='append', index=False ) # 写入完成后主动拉取当前会话的所有警告信息 session_warnings = connection.exec_driver_sql("SHOW WARNINGS").fetchall() if session_warnings: print("写入过程捕获到以下警告:") for warn_item in session_warnings: print(warn_item) except Exception as e: print("Failed to insert record into Transaction table {}".format(e)) engine.dispose() print("MySQL connection is closed")
效果说明
- 所有字段长度超限被截断、数值超出字段范围被转换、空值写入非空字段的提示,都会在写入完成后逐行打印出来
- 不会因为单个警告中断全量数据的写入流程,符合日常批量导入的使用习惯
- 不会遗漏客户端没有自动上报的服务端警告,所有和当前会话相关的提示都会被
SHOW WARNINGS查询兜底获取到
内容的提问来源于stack exchange,提问作者priya
相关产品推荐
相关产品推荐

