本地开发或轻量任务用 schedule,生产环境或需持久化/分布式/失败重试时必须用 APScheduler;前者简洁但进程退出即停,后者支持后台运行、job 持久化及异常捕获。

用 schedule 还是 APScheduler?别选错场景
直接结论:本地开发或轻量任务用 schedule,生产环境或需持久化/分布式/失败重试时必须上 APScheduler。前者 API 简洁但进程退出就停,后者支持后台运行、job 持久化到 SQLite 或数据库,且能捕获异常不中断调度。
常见错误是把 schedule.every().day.at("09:00").do(export_to_excel) 写完就扔进脚本里直接跑——它不会自动启后台线程,得手动加 schedule.run_pending() 循环,否则根本不动。
实操建议:
- 测试阶段用
schedule+time.sleep(1)循环,简单直观 - 部署到 Linux 服务器时,用
APScheduler配合BackgroundScheduler,并设置coalesce=True防止漏执行 - Windows 服务场景下,
APScheduler必须搭配BlockingScheduler,否则主进程退出后定时器失效
pandas.read_sql 导出前必须处理的三类数据库问题
不是所有 SQL 查询都能直接喂给 pandas.read_sql。常见卡点在字符集、时间类型和 NULL 值映射。
典型现象:中文字段导出 Excel 后变乱码、datetime 列在 Excel 里显示为数字、空值被转成 NaN 但 Excel 单元格留白不统一。
实操建议:
- MySQL 连接字符串加
?charset=utf8mb4,避免read_sql解码失败 - PostgreSQL 时间字段用
CAST(created_at AS TEXT)或pandas.to_datetime()显式转换,防止 Excel 识别错格式 - 对可能含 NULL 的列,用
df.fillna("")统一替换,否则openpyxl写入时会报InvalidFileException
用 openpyxl 写 Excel 比 ExcelWriter 更稳的两个理由
pandas.ExcelWriter 默认用 xlsxwriter 引擎,不支持读取已有文件、不能写入公式、也无法操作单元格样式——而日报导出常需加表头样式、冻结首行、自动列宽。
错误做法是先用 ExcelWriter 写完再用 openpyxl 打开改样式,这会触发两次 I/O 且容易损坏文件。
实操建议:
- 直接用
openpyxl.Workbook()创建新工作簿,用ws.append()写数据行,比to_excel更可控 - 写完后调用
ws.column_dimensions["A"].width = 20手动设列宽,避免 Excel 自动压缩中文列 - 加冻结首行:
ws.freeze_panes = "A2";加粗表头:ws["A1"].font = Font(bold=True)
Linux 定时启动 Python 脚本时,PATH 和 working directory 最容易被忽略
用 crontab -e 加 0 9 * * * /usr/bin/python3 /home/user/report.py 后脚本静默失败?大概率是路径问题。
现象包括:找不到数据库驱动(ModuleNotFoundError: No module named 'pymysql')、导出文件写到根目录或家目录下、相对路径的配置文件读不到。
实操建议:
- 在 crontab 中显式指定
PYTHONPATH和PATH:PATH=/usr/local/bin:/usr/bin:/bin PYTHONPATH=/home/user/venv/lib/python3.9/site-packages 0 9 * * * /home/user/venv/bin/python3 /home/user/report.py - 脚本开头加
os.chdir(os.path.dirname(__file__)),确保相对路径行为一致 - 导出文件路径写绝对路径,比如
/home/user/reports/report_$(date +\%Y\%m\%d).xlsx,别用./output/
复杂点在于数据库连接池和 Excel 文件句柄——如果每天导出后没显式关闭连接、没释放 openpyxl.Workbook 对象,跑一周后可能因 fd 耗尽而失败,这个细节几乎没人检查。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











