Python处理海量数据表执行删除操作时logging日志不打印问题咨询
首先排除str.format长度限制问题
Python 3.8的str.format方法不存在实用场景下的长度限制,你单次传入的t1_list仅50个元素,拼接后的SQL总长度最多仅数千字符,远未达到Python字符串的长度上限,该可能性可以直接排除。
日志不输出的核心原因
你遇到的大表场景下日志不输出、小表场景正常的问题,大概率是以下两个原因共同导致的:
日志级别配置不符合预期
Python logging模块默认的全局日志级别为WARNING,仅级别大于等于WARNING的日志才会被输出。你代码中的logger.debug()属于DEBUG级别、logger.info()属于INFO级别,均低于默认的WARNING阈值,如果没有手动修改过logger的级别配置,这两类日志默认会被直接过滤。
你提到小表场景下日志正常,大概率是小表测试时你修改过日志级别配置,或者测试环境的logging配置和生产环境不同。日志缓冲区未及时冲刷
如果确认已经配置了正确的日志级别,那问题就出在日志缓冲区机制上:
Python logging输出到终端、文件时默认带有缓冲区,只有当缓冲区满、程序退出、或者遇到强制冲刷指令时,才会将缓冲区中的日志内容写入输出目标。
处理大表时,cursor.execute(del_query)会阻塞非常久(数据库执行大表删除操作耗时很长),这时候你打印的日志还停留在缓冲区中没有被刷出,就会出现日志没打印的假象。而小表删除时execute执行速度快,程序很快进入下一轮迭代甚至直接结束,缓冲区会被自动冲刷,所以你能正常看到日志输出。
修复方案
1. 明确配置日志级别
在脚本初始化logging的位置添加如下配置,确保INFO、DEBUG级别的日志能被正常捕获:
import logging # 全局配置所有logger的级别和输出格式 logging.basicConfig( level=logging.DEBUG, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", force=True # Python 3.8+支持,强制覆盖已存在的默认配置 )
如果只需要修改当前业务logger的级别,可以单独配置:
logger = logging.getLogger('sspurge.' + __name__) logger.setLevel(logging.DEBUG) # 若没有绑定handler,额外添加控制台输出handler if not logger.handlers: console_handler = logging.StreamHandler() console_handler.setLevel(logging.DEBUG) formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") console_handler.setFormatter(formatter) logger.addHandler(console_handler)
2. 开启日志即时冲刷
如果是输出到文件,可以在配置FileHandler时设置行缓冲:
file_handler = logging.FileHandler("purge.log", mode="a", buffering=1)
也可以在重要日志打印后手动冲刷缓冲区:
logger.info("Deletion iteration started from source") for handler in logger.handlers: handler.flush()
额外优化建议
- 你当前使用字符串拼接SQL的方式存在SQL注入风险,建议改成参数化查询实现。
- 每次执行delete后可以打印
cursor.rowcount确认本次删除的行数,更直观的判断清理进度。 - 5亿条大表的删除操作建议分批提交,避免长事务导致数据库性能恶化。
内容的提问来源于stack exchange,提问作者Ramanathan Chellappan

