Python操作MySQL自动查询昨日至当日时间段数据的实现方案
实现方案
你可以根据部署场景二选一,优先选择第一种方案,可控性更高。
方案1:Python侧计算时间 + 参数化查询(推荐)
这种方案不会受Python和MySQL时区不一致的影响,也能避免SQL注入风险,是生产环境的标准写法。
核心逻辑是用Python内置datetime模块自动计算对应区间的起止时间,再通过参数化传入SQL执行:
from datetime import datetime, timedelta # 计算时间区间:固定时分秒为业务要求的18:30:00到18:29:30 current_date = datetime.today().date() end_dt = datetime.combine( current_date, datetime.strptime("18:29:30", "%H:%M:%S").time() ) start_dt = end_dt - timedelta(days=1) # 执行参数化查询,禁止直接拼接字符串到SQL中 sql = """ SELECT concat(FORMAT(Sum(RealCash),0)) FROM fantasy.Transaction WHERE TransactionType = 4 AND Status = 1 AND DateModified BETWEEN %s AND %s """ my_cursor.execute(sql, (start_dt, end_dt)) # 获取查询结果 res = my_cursor.fetchone()
如果服务部署在非本地时区,替换datetime.today()为对应时区的当前时间获取逻辑即可,比如用Python3.9+自带的zoneinfo模块指定业务时区,避免服务器系统时间和业务时间不匹配。
方案2:MySQL内置函数实现(无需Python传参)
如果确认MySQL服务时区和业务要求的时区完全一致,可以直接把时间计算逻辑写在SQL里,代码更简洁:
# 直接执行固定SQL即可,不需要动态传参 my_cursor.execute(""" SELECT concat(FORMAT(Sum(RealCash),0)) FROM fantasy.Transaction WHERE TransactionType = 4 AND Status = 1 AND DateModified BETWEEN DATE_SUB(CONCAT(CURDATE(), ' 18:30:00'), INTERVAL 1 DAY) AND CONCAT(CURDATE(), ' 18:29:30') """) res = my_cursor.fetchone()
注意事项
- 不要用f-string、字符串format直接把时间拼接到SQL语句里,既容易出现时间格式不兼容的问题,也存在SQL注入风险。
- 首次上线前建议单独打印计算出的起止时间,核对和预期的查询区间完全一致后再正式使用,避免时区配置错误导致数据统计偏差。
内容的提问来源于stack exchange,提问作者Yogesh
相关产品推荐
相关产品推荐

